Complete guide to host multiple WordPress sites in a LEMP stack in a Ubuntu 16.04 LTS. Installation of SSL by Let’s Encrypt has been illustrated also.
Buy a VPS
This is the right time to move your sites from shared hosting to a VPS if you are getting moderate traffic for your sites. You can purchase a VPS with a minimum price of $5 per month from DigitalOcean.
You should select nearest data center region. Note down the ip address of the newly created droplet.
Login to your droplet
In Windows install Putty. Open it with ip address.
A security alert will pop up. Click Yes. Login as root.
Set a Hostname
Execute:
hostnamectl set-hostname wordpress nano /etc/hosts
Change the line of text where the cursor is, to
127.0.1.1 wordpress
Verify:
hostname
You will get wordpress as output.
Set Timezone
Execute:
dpkg-reconfigure tzdata
Verify:
date
It will show your local date and time.
Create User
adduser admin
usermod -a -G sudo admin logout
Run Putty again and login as admin.
Lock with a Private Key
Open puTTYgen. Generate a Public/Private key pair.
Save Private key in your PC.
Copy Public key.
Execute:
mkdir .ssh sudo nano .ssh/authorized_keys
Paste the copied public key into this file.
Save and Exit.
Execute:
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 and password authentication:
PasswordAuthentication no PermitRootLogin no
Execute:
sudo service ssh restart
Open the private key and login with admin user. No password is necessary.
Firewall Setup
Execute:
sudo ufw app list sudo ufw allow OpenSSH sudo ufw enable sudo ufw status
Install Nginx
Execute:
sudo apt-get update sudo apt-get install nginx sudo ufw allow 'Nginx HTTP' sudo ufw status
Open your browser and type IP address. You will see the following:
Configure Default Virtual Host
Execute:
sudo nano /etc/nginx/sites-available/default
Edit:
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.php index.html; server_name _; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~ /\.ht { deny all; } }
Create Virtual Host for example.com
Create root directory for example.com
Execute:
sudo mkdir /var/www/html/example
Execute:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com sudo nano /etc/nginx/sites-available/example.com
Edit:
server { listen 80; listen [::]:80; root /var/www/html/example; index index.php index.html; server_name example.com; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~ /\.ht { deny all; } }
Execute:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled sudo service nginx restart
Multiple Virtual Host
Repeat the above process for example2.com and so on.
Now you can see example.com, example2.com etc in your browser if you have already changed DNS records of the domains pointing to new host.
Install MySQL Server
Execute:
sudo apt-get install mysql-server sudo mysql_secure_installation
Since you have already set up a password for your root user, you can answer “no” to the question for changing root password. Answer “yes” to rest of other questions.
Create MySQL Databases
Execute:
mysql -u root -p show databases; CREATE DATABASE wpdb1 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; GRANT ALL ON wppdb1.* TO 'wp_user'@'localhost' IDENTIFIED BY 'wp_password'; FLUSH PRIVILEGES; EXIT;
Similarly, you can create as many database as you need.
PHP-FPM Install
Execute:
sudo apt-get install php-fpm php-mysql php-xml php-gd sudo nano /etc/php/7.0/fpm/php.ini
Set:
cgi.fix_pathinfo=0; post_max_size = 20M upload_max_filesize = 20M
Restart:
sudo service php7.0-fpm restart sudo service nginx restart
Execute:
sudo nano /var/www/html/test.php
Browse:
http://ipaddress/test.php
if it results the following then all is okay. Now you can remove the test file.
sudo rm /var/www/html/test.php
Install WordPress
Execute:
sudo wget https://wordpress.org/latest.zip sudo apt-get install unzip sudo unzip latest.zip sudo cp -R wordpress/* /var/www/html/example/ cd /var/www/html/ chown -R www-data example
Hit the browser:
http://example.com
You should see:
Continue the installation:
Transfer files from Old Host to New Host
If you are migrating from any other host you should transfer your files as well as database.
Follow this guide: How to Copy Files from Old Host to New Host
Secure example.com with SSL
Now that you have successfully hosted many wordpress sites. You may secure example.com with a FREE SSL provided by Let’s Encrypt.
Execute:
sudo ufw disable sudo service nginx stop sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 sudo nano /etc/nginx/snippets/ssl-params.conf
Add:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;
Execute:
sudo nano /etc/nginx/sites-available/example.com
Change to:
server { listen 80; listen [::]:80; server_name example.com; return 301 https://$server_name$request_uri; } server { server_name www.example.com; return 301 $scheme://example.com$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; include snippets/ssl-params.conf; root /var/www/html/example; index index.php index.html; server_name example.com; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~ /\.ht { deny all; } location ~ /.well-known { allow all; } }
Execute:
git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt ./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory --help ./letsencrypt-auto certonly -a webroot --webroot-path /var/www/html/example -d example.com -d www.example.com --server https://acme-v01.api.letsencrypt.org/directory --agree-dev-preview sudo service nginx restart
As the SSL certificate should be renewed every three months, you should add the following to automate the renewal process.
Execute:
sudo crontab -e 30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log 35 2 * * 1 /bin/systemctl reload nginx
Now hit the browser, you will be redirected to https://example.com with a green padlock. Happy Browsing.
Leave a Reply