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:
- http://domain1.com
- http://www.domain2.com
- https://www.domain3.com
- https://domain4.com
- https://subdomain1.domain4.com
- 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.:
- http://www.domain1.com will be redirected to http://domain1.com
- http://domain2.com will be redirected to http://www.domain2.com
- https://domain3.com will be redirected to https://www.domain3.com
- https://www.domain4.com will be redirected to https://domain4.com
- https://www.subdomain1.domain4.com will be redirected to https://subdomain1.domain4.com
- 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.