Set Up Nginx with Virtual Hosts

Nginx is an amazing web server. Virtual hosts allow for many sites to be piled onto a single server. The following how-to outlines the process of getting WordPress blogs up and running to make the most out of available hardware. Over a dozen sites and millions of page views per month can be hosted on something as basic as an AWS EC2 micro tier cloud instance!

This guide has been tested and confirmed working on a lightweight Ubuntu 14.04.1 server.

First, install the LEMP stack.

sudo apt-get install nginx mysql-server php5-fpm php5-mysql

Be sure to remember the MySQL root password set during installation. You’ll need it in a minute.

Securing and optimizing a web server could be an entire encyclopedia on its own. I’ll save the serious tuning for another post, but at the very least we need to make one change to PHP.

sudo nano /etc/php5/fpm/php.ini

Find the following line, uncomment it and make sure it’s set to zero.


Ctrl-O to save and Ctrl-X will get you back to a command line.

Time to set up WordPress. At this point, you could potentially replicate the following steps on the same single instance, making necessary changes for each domain. A ton of low traffic blogs (15+) could run on a single AWS t2.micro, which can be had for as little as ~$55 a year if you prepay for a dedicated instance.

Set up a database and user for the new WordPress installation in MySQL.

Log in as the root database admin:

mysql -­u root ­-p

After entering the root password, you will be presented with the MySQL command prompt.


Execute the following commands line by line, pressing Enter after each semicolon. Change the bold database name, user, and password to uniquely identify the website to which it belongs. Record this information somewhere handy, you’ll need it a minute.

Pay close attention! Don’t miss things like the asterisk and single quotes, they are important. Watch for syntax errors, MySQL will let you know if a query does not execute properly. After you run each command you should see something to the effect of:

Query OK, 1 row affected (0.00 sec)

At the mysql> prompt:

CREATE DATABASE wordpressdbname;

GRANT ALL PRIVILEGES ON wordpressdbname.* TO wordpressuser@localhost IDENTIFIED BY 'wordpresspass';



This will drop out to the Linux CLI.

Now to put the puzzle pieces together. Get the latest version of WordPress:


Unpack this to the home directory for now.

tar ­-zxvf latest.tar.gz

A few edits need to be made before moving into production. There should now be a new directory called “wordpress”. This contains everything necessary for a fresh installation. Set up the configuration file to reflect the unique details of the new site.

cd wordpress/

mv wp­-config-­sample.php wp­-config.php

nano wp-­config.php

Make the necessary changes on the following lines:

define('DB_NAME', 'wordpressdbname');

define('DB_USER', 'wordpressuser');

define('DB_PASSWORD', 'wordpresspass');

Scroll down a bit to “Authentication Unique Keys and Salts” and do a find­-and­-replace for:

‘put your unique phrase here’

Anything will work as long as it’s sufficiently long. Don’t forget to keep the single quotes, they’re important syntactically.

After double­-checking that the information is correct, save the file (Ctrl-­O) and exit back out to the CLI (Ctrl-­X).

Back out to the main home directory and move the WordPress folder to its permanent home. This should be done as sudo, since /var/www has enforced permissions. This is a great time to rename the wordpress folder to reflect the site it represents, especially important with a multi­site (virtual host) nginx instance.

cd ~

sudo mv wordpress/ /var/www/name_the_site

Change ownership of the directory to the web services user.

sudo chown ­-R www­-data. /var/www/name_the_site

Time to make nginx aware of the new site by creating a corresponding virtual host file.

sudo nano /etc/nginx/sites-­available/name_the_site

Paste the following into the file, making the necessary changes to the bold bits:

server {
listen 80;
root /var/www/name_the_site;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5­-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;

The finish line is in sight. Now to create a symbolic link that will actually “flip the switch” to make the site live in the eyes of nginx.

sudo ln ­-s /etc/nginx/sites-­available/name_the_site /etc/nginx/sites-­enabled/name_the_site

Restart the services for nginx and php5­-fpm and everything server­-side is ready for action.

sudo service nginx restart

sudo service php5­-fpm restart

Point the HOST A record at the correct IP address of the web server and you should be greeted by a fresh WordPress installation when you bring up the site in a browser:­-admin/install.php

You win!

Feel free to leave a comment and let me know how it works for you!

If you appreciate my hard work, PayPal me a frosty beverage.

1 comment

Leave a comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.