How to Install Multiple WordPress with Nginx on Ubuntu 18.04

Imagine, if you have only single server but 2 or more WordPress sites, you think you need more server to run each wordpress site on it. It's fine, but how about if you don't have a lot of costs to maintain many servers.

This article will show you how to run multiple WordPress website on one host server, using Nginx + Mariadb + php-fpm on Ubuntu 18.04 LTS .

Prerequisites

1) Nginx for webserver

2) Mariadb for mysql database

3) php-fpm for php FastCGI Process Manager

Those command will update your system and add new repository for php packages

# apt-get update
# apt-get install software-properties-common 
# add-apt-repository ppa:ondrej/php

Install Nginx, Mariadb and php-fpm

We will install Webserver Nginx, mysql server Mariadb and php7-fpm as well as php7 extension needed to run WordPress site

# apt-get install nginx mariadb-server mariadb-client \ 
php7.0-fpm php7.0-common php7.0-mbstring php7.0-xmlrpc \
php7.0-soap php7.0-gd php7.0-xml php7.0-intl php7.0-mysql \
php7.0-cli php7.0-mcrypt php7.0-ldap php7.0-zip php7.0-curl -y

Config Mariadb server

For refresh database server installation, we need config for mysql root password and other options

This command run in wizard mode, just answer the question and apply it by 'Enter'

# mysql_secure_installation

...

Enter current password for root (enter for none): #< Enter
...

Change the root password? [Y/n] y #< type 'y' then Enter
New password: #< Type mysql root password
Re-enter new password: #< Retype mysql root password
Password updated successfully!
Reloading privilege tables..
... Success!

...

Remove anonymous users? [Y/n] y #< type 'y' then Enter
... Success!

...

Disallow root login remotely? [Y/n] y #< type 'y' then Enter
... Success!

...

Remove test database and access to it? [Y/n] y #< type 'y' then Enter
...

Reload privilege tables now? [Y/n] y #< type 'y' then Enter
...

Thanks for using MariaDB!

Check Mariadb service and enable service at boot

To make sure mariadb-server is running and confirm all setting up you did in previous steps.

If there are have no error, Mariadb-server ready to serve database service

# systemctl status mariadb
● mariadb.service - MariaDB database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-07-16 03:11:48 UTC; 4h 19min ago
Main PID: 10781 (mysqld)
Status: "Taking your SQL requests now..."
Tasks: 27 (limit: 2322)
CGroup: /system.slice/mariadb.service
└─10781 /usr/sbin/mysqld

Replace 'password' with your password you have input in previous step

# mysql -uroot -p'password'

Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 49
Server version: 10.1.29-MariaDB-6 Ubuntu 18.04

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Look good, now enable mysql service at boot

# systemctl enable mariadb

Config php-fpm

Nginx does not support to run php like mod_php in Apache.

So we need install (we did it) and config php-fpm daemon that support running php source code

Edit file /etc/php/7.0/fpm/php.ini with some parameters like below

# vim /etc/php/7.0/fpm/php.ini

upload_max_filesize = 100M
max_execution_time = 360
cgi.fix_pathinfo = 0
date.timezone = Asia/Ho_Chi_Minh

Check php-fpm pool config file /etc/php/7.0/fpm/pool.d/www.conf

Make sure this configuration have, leave default other options if you not good at all:

user = www-data
group = www-data
listen = /run/php/php7.0-fpm.sock
listen.owner = www-data
listen.group = www-data

Now just restart php-fpm daemon and check status, then enable service at boot

# systemctl restart php7.0-fpm
# systemctl status php7.0-fpm
# systemctl enable php7.0-fpm

Create multiple wordpress site

Example, we have 3 wordpress sites, name:

- site1.example.com
- site2.example.com
- site3.example.com

Create database

We will create db for site1, site2, site3 and grant db user for those databases

site1.example.com will run database name 'site1' with database user is 'site1'@'localhost'

mysql -u root -p'password' -e "CREATE DATABASE site1;"
mysql -u root -p'password' -e "GRANT ALL PRIVILEGES ON site1.* TO 'site1'@'localhost' IDENTIFIED BY 'site1password';"
mysql -u root -p'password' -e "FLUSH PRIVILEGES;"

Do the same action for site1, site2 database, replace 'site1' with site2, site3. Replace db user password if you want

mysql -u root -p'password' -e "CREATE DATABASE site2;"
mysql -u root -p'password' -e "GRANT ALL PRIVILEGES ON site2.* TO 'site2'@'localhost' IDENTIFIED BY 'site2password';"
mysql -u root -p'password' -e "FLUSH PRIVILEGES;"
mysql -u root -p'password' -e "CREATE DATABASE site3;"
mysql -u root -p'password' -e "GRANT ALL PRIVILEGES ON site3.* TO 'site3'@'localhost' IDENTIFIED BY 'site3password';"
mysql -u root -p'password' -e "FLUSH PRIVILEGES;"

Create nginx configuration file for each site

Every time you want to add new site, just add new server block for that site

# cat > /etc/nginx/sites-available/site1.conf <<EOF
server {
listen 80;
root /var/www/site1;
index index.php index.html index.htm;
server_name site1.example.com www.site1.example.com;

client_max_body_size 100M;

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

location ~ \.php\$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
}
}
EOF

Do the same action for site2 and site3

Then we will have 3 new config file in /etc/nginx/sites-available/. You can check to verify configuration bay cat command

#cat  /etc/nginx/sites-available/site2.conf
server {
listen 80;
root /var/www/site2;
index index.php index.html index.htm;
server_name site2.linoxide.com www.site2.linoxide.com;

client_max_body_size 100M;

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

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

Create Document root for each site

NOTE: Document root path must be same in Nginx configuration (parameter 'root' in server{} block) and have owner is www-data

If you want to change document root directory, just change the 'root' option in nginx config and create same path.

# mkdir -p /var/www/site{1,2,3}
# chown -R www-data:www-data /var/www/site*

Enable nginx config for each site and check configuration

Because by default Nginx only read configuration in  /etc/nginx/sites-enabled/

So if you want to Nginx read configuration in /etc/nginx/sites-available/

Just simply create a symlink, like this:

# ln -s /etc/nginx/sites-enabled/site1.conf /etc/nginx/sites-available/site1.conf
# ln -s /etc/nginx/sites-enabled/site2.conf /etc/nginx/sites-available/site2.conf
# ln -s /etc/nginx/sites-enabled/site3.conf /etc/nginx/sites-available/site3.conf

Then verify Nginx config by run this command:

# nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Look good configuration, reload Nginx daemon

# nginx -s reload -c /etc/nginx/nginx.conf

or

# systemctl reload nginx

Download wordpress source and place to /var/www/site*

NOTE: If you have existed wordpress source, just place it to Document root path follow nginx configuration.

# cd /tmp
# wget http://wordpress.org/latest.tar.gz
# tar -xzvf latest.tar.gz
# cp -r wordpress/* /var/www/site1/
# cp -r wordpress/* /var/www/site2/
# cp -r wordpress/* /var/www/site3/
# chown -R www-data:www-data /var/www/site*

Initial for fresh wordpress installation

Access each site that you want to init WordPress by using the browser. After choosing your language, click 'Continue' button

Then fill the database name, database user, database password to run config for each site, like below

wp init config

Then submit your config and 'run installation' by click 'Run the installation' button.

Read also:

Now, with Nginx, Mysql and php-fpm, you can run many site WordPress in one server. Not only WordPress but also you can do same steps for other cms source.

Next article, we will explain and guide how to optimize nginx, php-fpm configuration for web server running Nginx and php-fpm

Nguyen Anh Tuan 5:27 am

About Nguyen Anh Tuan

Expertise in Linux system, Linux networking and internet service, 8 years experiences with Linux/Unix. Passionate with OpenStack cloud platform, expertise in KVM virtualization.

Author Archive Page

Have anything to say?

Your email address will not be published. Required fields are marked *

All comments are subject to moderation.

2 Comments

  1. Hi Stefan,
    It's a good question
    This article I just show an example 'howto', so I used only 1 socket for all website
    But if you config in production or shared environment, it's should have separator php-fpm pool, user as well as socket listener for each site.
    If you want to know more about php-fpm configuration, you can refer http://php.net/manual/en/install.fpm.configuration.php