Nginx

How to configure Nginx for Wordpress Multisite with subdirectories

Multisite specific directives

wordpress 589121 640
Credit: pixabay

I've been running Wordpress on Nginx for a couple of years now with great success in our data center. We host roughly 100 installs on modestly provisioned VMs, some that handle 1 million+ page views per month. With a few specific Nginx directives you can also deploy Wordpress Multisite in either Subdomain or Subdirectory format, but the documentation on the later is confusing. This post is an attempt to make the steps clear and concise. 

[ See also: How to get started with Nginx ]

Before you go down this path however, I would encourage you to look closely at the business needs and make sure you actually need/want a multisite install. There are a lot of misconceptions. Here are some good reads to help you make your decision:

Still making the right choice? Here's how to get it configured under Nginx.

Step 1

Install Wordpress as you normally would for a single site. This isn't a guide for starting from scratch with Wordpress and Nginx, but here is a good tutorial for that.

Once your site is set up and configured as a normal Wordpress install, enable the Multisite option by adding a line to your wp-config.php file. Add this line just above where it says "/* That's all, stop editing! Happy blogging. */":

/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );

A new option will appear in the Admin panel of Wordpress under Tools -> Network Setup

800px network create wordpress.org
wordpress.org

Step 2

Choose the Subdirectory install option and click Install. Once completed, you'll have some new lines to add to your wp-config.php file. These lines will differ based on your installation but will be provided for you after the install has completed.

800px tools network created Wordpress.org

Copy the 6 new lines into your wp-config file and ignore the .htaccess rules for now.

You'll now have a separate "Site" called Network Admin in the upper left of your Admin section.

network admin link Wordpress.org

Step 3

Create a new site in your network for test purposes (or a real one if you want). When you do, you'll specify the subdirectory path you want to use for the site. The process should complete successfully, but visiting the URL will not work properly yet.

Under the Network Admin section, install a new Plugin called Nginx Helper. Once installed and activated, visit the plugin settings page and check the box next to "Enable Nginx Map." This will display a new section showing a file system path to your map file and the actual site mappings that are being generated.

screenshot 2 Wordpress.org

These nginx mappings are the key to getting subdirectories working in multisite. Each new site in your network will have both a directory path as well as a blog id. The mapping links the subdirectory in the URL with the proper site in the database. Keep the Nginx Map path handy for the next step.

Step 4

Almost there, we just need to configure Nginx to work with multisite and subdirectories now. This requires terminal access to the site's Nginx vhost file, usually through SSH. If you don't know what that means, you'll need to contact your server administrator. 

SSH to the Nginx site configuration file, on Debian/Ubuntu it's at /etc/nginx/sites-available

Use your favorite text editor to modify the .vhost file of the site you're working on.

At the top of the file, outside the server{} block, add the following map directive using the Nginx map path from Step 3:

map $http_host $blogid {
    default 0;
    include /var/www/pathtoyoursite/wp-content/uploads/nginx-helper/map.conf;
}

This will read the blog mappings generated by the Nginx Helper plugin. Including it this way will let the plugin update the mappings file automatically as you add new sites and you won't have to change your Nginx config again.

Finally, still in your .vhost file, add the following Nginx directives at the bottom of the server{} block, replacing any existing Wordpress directives you've already defined, usually following the location @php{} directive:


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

location ~ ^/files/(.*)$ {
  try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ;
  access_log off; log_not_found off; expires max;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
	expires 24h;
	log_not_found off;
}

location ^~ /blogs.dir {
	internal;
	alias /var/www/pathtoyoursite/web/wp-content/blogs.dir ;
	access_log off; log_not_found off;      expires max;
}


if (!-e $request_filename) {
	rewrite /wp-admin$ $scheme://$host$uri/ permanent;
	rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
	rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
}

Note the alias line in the second to last directive block, you'll need to update that with the path to your wordpress install.

Final Step

Restart nginx to apply the settings.

ITWorld DealPost: The best in tech deals and discounts.
Shop Tech Products at Amazon