Students tutorial – How to Run Multiple WordPress Blogs on Single Nginx Server

Want to run multiple WordPress blogs or websites on a single Nginx web server? Just like our previous tutorial that shows you how to host multiple websites on Apache2, this brief tutorial will show you how to do the same using Nginx.

Nginx server block is a feature similar to Apache2 virtualhost. These features allow users and students host multiple independent websites or blogs on a single host computer with single IP with separate domain names.

Using server blocks or virtualhosts, one can save on cost of additional servers or resources.

When you’re ready, follow the steps below to get this working.

Step 1: Setup Ubuntu Linux

We’re using Ubuntu Linux because it’s easier to use and manage, especially for new users and students. Other Linux server will let you do the same, but I find Ubuntu to be much more user friendly then other Linux distributions.

So, setup Ubuntu server and run the commands below to update it.

sudo apt-get update && sudo apt-get dist-upgrade && sudo apt-get autoremove

Step 2: Install Nginx Web Server

WordPress requires a web server to function. There are many web servers that will work with WordPress, however, since this post is about Nginx, we’re going to be installing Nginx. To do that, run the commands below

sudo apt-get install nginx

Step 3: Install MySQL Database Server

After installing Nginx web server, run the commands below to install MySQL database server. WordPress also requires databases in order to function. To install MySQL, run the commands below

sudo apt-get install mysql-server mysql-client

During the installation of MySQL server, you’ll be prompted to create a new password and confirm it for MySQL root user. Do it.

Step 4: Install PHP-FPM and other PHP modules

After installing MySQL server, run the commands below to install PHP and other PHP based modules. WordPress requires these to function properly.

sudo apt-get install php-fpm php-mysql php-fpm php-curl php-gd php-pear php-imagick php-imap php-mcrypt php-recode php-tidy php-xmlrpc

After installing PHP and modules, continue below to create a new databases and user for WordPress.

Step 5: Create WordPress databases and users

Now that all the required server and packages are installed, go a create WordPress databases for as many sites as possible. If you’re going to be running two independent sites, create two databases and users. If more then two, then create as many.

Run the commands below to sign onto MySQL server using the password created above.

sudo mysql -u root -p

Then run the commands below to create a new database called wpsite1db and wpsite2db for WordPress site #1 & #2

CREATE DATABASE wpsite1db;
CREATE DATABASE wpsite2db;

Next, run the commands below to create new WordPress users called wpuser1 and wpuser2 for site 1 and 2 and grant them access to their respective site

GRANT ALL ON wpsite1db.* TO 'wpuser1'@'localhost' IDENTIFIED BY 'type_new_password_here';
GRANT ALL ON wpsite2db.* to 'wpuser2'@'localhost' IDENTIFIED BY 'typw_new_passwored_here';

You can create as many databases and sites for run many different websites and blogs.

When you’re done, run the commands below to save your changes and exit.

FLUSH PRIVILEGES;
exit;

Step 6: Create As Many Server Blocks As Possible

Server blocks are just individual site configuration file. Each site will have its own server block file. So the trick is to copy the default server block config and create as many from it. So, let’s create two WordPress websites called example.com and example.net from the default config file by running the commands below.

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.net

After creating the server blocks or site configuration files, open each file and make the highlighted file to match each domain.

sudo nano /etc/nginx/sites-available/example.com

Make below changes and save.

# Default server configuration
#
server {
        listen 80;
        listen [::]:80;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;
        root /var/www/html/example.com;
        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;
        server_name example.com www.example.com;
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #
        #       # With php7.0-cgi alone:
        #       # fastcgi_pass 127.0.0.1:9000;
        #       # With php7.0-fpm:
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}

Do the same for example.net and replace all example.com references with example.net and save the file.

Run the commands below to edit example.net file.

sudo nano /etc/nginx/sites-available/example.net

Then change example.com references with example.net and save.

When you’re done, run the commands below to enable both server blocks and delete the default configuration.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example.net /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-available/default

Then run the commands below to disable Apache2 web server

sudo systemctl stop apache2
sudo systemctl disable apache2

Step 7: Create Multiple DocumentRoot directories

In each of the server block or site configuration file, there’s a root location. This is where each website content should be stored.. and should be different for all websites. Now that we’ve defined the root locations for all our site, go and create them below.

sudo mkdir -p /var/www/html/example.com
sudo mkdir -p /var/www/html/example.net

Step 8: Download WordPress content and copy it to each of the root location

Now download WordPress content and extract into the root directory for each site. To do that run the commands below

cd /tmp/ && wget http://wordpress.org/latest.tar.gz

Then extract the downloaded file.

tar -xzvf latest.tar.gz

And copy to each root folder for each site.

sudo cp -R wordpress/* /var/www/html/example.com
sudo cp -R wordpress/* /var/www/html/example.net

STEP 9: CONFIGURE WORDPRESS DATABASE SETTINGS

Run the commands below to create WordPress wp-config.php settings file from its sample for each domain.

sudo cp /var/www/html/example.com/wp-config-sample.php /var/www/html/example.com/wp-config.php
sudo cp /var/www/html/example.net/wp-config-sample.php /var/www/html/example.net/wp-config.php

Then open wp-config.php file and make the following highlighted changes to reference the database and user you created above.

sudo nano /var/www/html/example.com/wp-config.php

When the file opens, make the changes and save.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wpsite1db');

/** MySQL database username */
define('DB_USER', 'wpuser1');

/** MySQL database password */
define('DB_PASSWORD', 'type_password_here');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

Do the above for each of the sites you create, making sure the database connection info is correct for each site.

Next, run the commands below to change the directory permissions so WordPress can function properly.

sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html

After that, restart Nginx web server

sudo nginx -t
sudo systemctl restart nginx

After restarting Nginx with no errors, you should be able to access your sites the domain names.. and see WordPress default setup page.

WordPress default setup page

Enjoy!