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.
Leave a Reply