Host Multiple Sites with SSL in Ubuntu 18.04


In this tutorial we shall share all the commands necessary to host multiple websites in a VPS server. We used VPS servers from Linode and Digital Ocean. Both are excellent and best value for money.

This is a comprehensive guideline to host following domains:

  1. http://domain1.com
  2. http://www.domain2.com
  3. https://www.domain3.com
  4. https://domain4.com
  5. https://subdomain1.domain4.com
  6. https://www.subdomain2.domain4.com

In the above examples 3, 4, 5 and 6 will use SSL provided by Let’s Encrypt for free.

Proper redirection rules will also be applied. E.g.:

  1. http://www.domain1.com will be redirected to http://domain1.com
  2. http://domain2.com will be redirected to http://www.domain2.com
  3. https://domain3.com will be redirected to https://www.domain3.com
  4. https://www.domain4.com will be redirected to https://domain4.com
  5. https://www.subdomain1.domain4.com will be redirected to https://subdomain1.domain4.com
  6. https://subdomain2.domain4.com will be redirected to https://www.subdomain2.domain4.com

All the above sites will be hosted in high performance secured web server named Nginx.

We will also share WordPress specific configuration and optimization of the performance to achieve a very good score in GTMetrix. In addition to the fresh installation guide, we will also discuss how to transfer your websites from existing host to the newly created host of high performance.

1. Initial Server Setup

From the dash board of VPS the first thing is to install an operating system. We prefer Ubuntu 18.04LTS because it’s simple and easy to use. Copy the IP address of your VPS. Run Putty to login as root user to the IP address.

1.1 Set Hostname

Set a hostname for your VPS e.g. “supercomputer”. Execute the following commands:

echo "supercomputer" > /etc/hostname
hostname -F /etc/hostname
nano /etc/hosts

Add: IP address <space> supercomputer

hostname

will give output “supercomputer”.

1.2 Set Timezone

Execute:

dpkg-reconfigure tzdata

Check with:

date

It will show you current date and time.

1.3 Create a Non-Root User

Execute:

adduser admin
usermod -aG sudo admin

1.4 Logout from Root

Now logout from root account. Run putty again and login as admin.

1.5 System Update

Execute:

sudo apt update
sudo apt upgrade

2. Secure Server

2.1 Secure with SSH Key Pair

Open puTTYgen from your own Windows PC.

Generate a Public/Private key pair.

Save Private key in your PC.

Copy Public key.

Login to the VPS using Putty as admin.

Execute:

mkdir .ssh
sudo nano .ssh/authorized_keys

Paste the copied public key into this file.
Save and Exit.

sudo chown -R admin:admin .ssh
sudo chmod 700 .ssh
sudo chmod 600 .ssh/authorized_keys
sudo nano /etc/ssh/sshd_config

Now disable root login by changing the following value:

PasswordAuthentication no
PermitRootLogin no

Restart SSH

sudo service ssh restart

Now you can not login with root account or using password. You only need to the private key to login.

2.2 Firewall Setup

sudo ufw app list

Output:
Available applications:
OpenSSH

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Output:
Status: active

3. Install LEMP Stack

3.1 Install Nginx

sudo apt install nginx
sudo nano /etc/nginx/nginx.conf

Add: server_names_hash_bucket_size 128;

3.2 Add Exception to Firewall

sudo ufw app list
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

3.3 Install MySQL

Execute:

sudo apt install mariadb-server php-mysql
sudo mysql_secure_installation
sudo mysql -u root -p
CREATE DATABASE testdb;
CREATE USER 'testuser' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON testdb.* TO 'testuser';
quit;

3.4 Install PHP

sudo apt install php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-soap php-xml php-xmlrpc php-zip
sudo systemctl restart php7.2-fpm

3.5 Increase File Upload Limit

sudo nano /etc/php/7.2/fpm/php.ini

Change: post_max_size = 200M
upload_max_filesize = 200M

sudo nano /etc/nginx/nginx.conf

Add: client_max_body_size 200m;

sudo service php7.2-fpm restart
sudo service nginx restart

4. Host Multiple Websites

4.1 Create directory and sub-directory for all the Domains and Sub-Domains

Execute:

sudo mkdir -p /var/www/html/domain1
sudo mkdir -p /var/www/html/domain2
sudo mkdir -p /var/www/html/domain3
sudo mkdir -p /var/www/html/domain4
sudo mkdir -p /var/www/html/domain4/subdomain1
sudo mkdir -p /var/www/html/domain4/subdomain2

4.2 Create Virtual Hosts

Execute:

sudo nano /etc/nginx/sites-available/domain1.com.conf

Add:

server {
    server_name    domain1.com www.domain1.com;
    root           /var/www/html/domain1;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
}

Execute:

sudo nano /etc/nginx/sites-available/domain2.com.conf

Add:

server {
    server_name    www.domain2.com domain2.com;
    root           /var/www/html/domain2;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
}

Execute:

sudo nano /etc/nginx/sites-available/domain3.com.conf

Add:

server {
    server_name    www.domain3.com domain3.com;
    root           /var/www/html/domain3;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
}

Execute:

sudo nano /etc/nginx/sites-available/domain4.com.conf

Add:

server {
    server_name    domain4.com www.domain4.com;
    root           /var/www/html/domain4;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
}

Execute:

sudo nano /etc/nginx/sites-available/subdomain1.domain4.com.conf

Add:

server {
    server_name    subdomain1.domain4.com www.subdomain1.domain4.com;
    root           /var/www/html/domain4/subdomain1;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
	
    if ($host ~* ^www\.(.*)) {
      set $host_without_www $1;
      rewrite ^(.*) http://$host_without_www$1 permanent;
    }
}

Execute:

sudo nano /etc/nginx/sites-available/subdomain2.domain4.com.conf

Add:

server {
    server_name    www.subdomain2.domain4.com subdomain2.domain4.com;
    root           /var/www/html/domain4/subdomain2;
    index          index.html index.php;

    location / {
      try_files $uri $uri/ /index.php?$args;
    }

    location ~* \.php$ {
      fastcgi_pass unix:/run/php/php7.2-fpm.sock;
      include         fastcgi_params;
      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
    }
}

4.3 Enable Virtual Hosts

Execute:

sudo ln -s /etc/nginx/sites-available/domain1.com.conf /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/domain2.com.conf /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/domain3.com.conf /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/domain4.com.conf /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/subdomain1.domain4.com.conf /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/subdomain2.domain4.com.conf /etc/nginx/sites-enabled
sudo service nginx restart

4.4 Check LEMP Working Status

Our LEMP system (Linux, Nginx, MySQL, PHP) is now ready to rock. However, we should to cross check whether everything so far is good.
Execute:

sudo nano /var/www/html/domain1/test.php

Add:


You should get, “You have connected successfully.”

Execute:

sudo rm /var/www/html/domain1/test.php
sudo mysql -u root -p
show databases;
use mysql;
select user, host from mysql.user;
delete from mysql.user where user='testuser';
drop database testdb;
exit;

4.5 Delete Virtual Hosts

Execute:

sudo ls /etc/nginx/sites-enabled

Check which vhost to delete and execute:

sudo rm -f /etc/nginx/sites-enabled/default
sudo rm -f /etc/nginx/sites-available/default
sudo service nginx restart

5. Install Let’s Encrypt SSL

5.1 Create SSL Certificates

sudo apt update && sudo apt upgrade
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python-certbot-nginx
sudo ufw allow 80
sudo certbot --nginx -d www.domain3.com -d domain3.com
sudo certbot --nginx -d domain4.com -d www.domain4.com
sudo certbot --nginx -d subdomain1.domain4.com -d www.subdomain1.domain4.com
sudo certbot --nginx -d www.subdomain2.domain4.com -d subdomain2.domain4.com

Check all existing SSL certificates.

sudo ls /etc/letsencrypt/live

To delete any of the above, Execute:

sudo certbot delete

5.2 Automatic Renewal of SSL Certificates

Execute:

sudo crontab -e

Add At the end:

15 3 * * * /usr/bin/certbot renew --quiet

6. Few Additional Steps

6.1 Leverage Browser Caching

Execute:

sudo nano /etc/nginx/sites-available/domain1.com.conf

Inside the Server block, Add:

location ~*  \.(jpg|jpeg|png|gif|ico|css|js|pdf)$ {
    expires 7d;
}

6.2 Set Proper file and folder Permission

Execute:

sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 775 {} \;
sudo find /var/www/html -type f -exec chmod 664 {} \;

6.3 Create Database for the Websites

Execute:

sudo mysql -u root -p
show databases;
CREATE DATABASE domain1 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON domain1.* TO 'd1username'@'localhost' IDENTIFIED BY 'd1password';
CREATE DATABASE domain2 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON domain2.* TO 'd2username'@'localhost' IDENTIFIED BY 'd2password';
CREATE DATABASE domain3 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON domain3.* TO 'd3username'@'localhost' IDENTIFIED BY 'd3password';
FLUSH PRIVILEGES;
EXIT;

6.4 Transfer Existing Sites from Old Host

To Export database from Old host, Execute:

mysqldump -u root -p databasename > dbname.sql

To Export selected tables, Execute:

mysqldump -u root -p databasename tablename1 tablename2 tablename3 > dbname.sql

Copy files from Old host to New host:

sudo scp -v -r admin@123.456.78.90:/home/admin/dbname.sql /home/admin/

To Import database in New host, Execute:

sudo mysql -u root -p newdbname < dbname.sql

You may also need to copy old files from old host to new host. Execute:

sudo scp -v -r admin@123.456.78.90:/var/www/domain1/* /var/www/html/domain1/

If old host is secured with SSH key pair, then Execute:

sudo nano /etc/ssh/sshd_config

Change:

PasswordAuthentication yes

Execute:

sudo service ssh restart

6.5 WordPress Installation

Execute:

sudo wget https://wordpress.org/latest.zip
sudo apt install unzip
sudo unzip latest.zip
sudo cp -R wordpress/* /var/www/html/domain1/
sudo rm latest.zip
sudo rm -rf wordpress
cd /var/www/html
chown -R www-data:www-data domain1

6.6 MyBB Installation

Execute:

sudo wget https://resources.mybb.com/downloads/mybb_1817.zip
sudo apt install unzip
sudo unzip mybb_1817.zip
sudo cp -R Upload/* /var/www/html/domain2/
sudo rm mybb_1817.zip
sudo rm -rf Upload
sudo rm -rf Documentation

6.7 Update DNS Settings

Set DNS of all the domains point to the correct IP address. You need to add A/AAAA records pointing to the IP address of the VPS.

That’s it. Hope you have successfully host websites in your own VPS. If you still have any query, you are free to ask. We surely get back to reply.

 

, , , ,

Leave a Reply

Your email address will not be published.