Update: This article is updated for WordPress 3.5 multisite’s file-handling and new W3-Total-Cache page-cache directory structure.
easyengine (ee) note: If you are using easyengine, you can accomplish everything in this article using following command:
ee site create example.com --wpsubdom --w3tc
In this article, we will setup WordPress Multisite using subdomains with Nginx with added support for W3 Total Cache Plugin.
If you haven’t created a WordPress Multisite network, please check this guide first.
Nginx Config
Below is recommended Nginx configuration.
server { ##DM - uncomment following line for domain mapping #listen 80 default_server; server_name example.com *.example.com ; ##DM - uncomment following line for domain mapping #server_name_in_redirect off; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; root /var/www/example.com/htdocs; index index.php; set $cache_uri $request_uri; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $cache_uri 'NULL'; } if ($query_string != "") { set $cache_uri 'NULL'; } # Don't cache uris containing the following segments if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") { set $cache_uri 'NULL'; } # Don't use the cache for logged in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") { set $cache_uri 'NULL'; } # Use cached or actual file if they exists, otherwise pass request to WordPress location / { try_files /wp-content/cache/page_enhanced${cache_uri}_index.html $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; } location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } location = /robots.txt { access_log off; log_not_found off; } location ~ /\. { deny all; access_log off; log_not_found off; } location ^~ /wp-content/w3tc- { deny all; access_log off; log_not_found off; } }
Above configuration is already tested for minification & browser caching. You can disable minification in W3-Total-Cache settings.
Domain Mapping
You need to uncomment few lines in above nginx-config to get domain-mapping working. Apart from above config changes, you can read this guide to setup/configure domain-mapping.
Must Read:
- Checklist For Perfect WordPress-Nginx Setup – It will help you verify if your caching will work after PHP/MySQL crash.
- Nginx Maps for Better Static File Handling in WordPress-Multisite – useful for multisite created before WordPress 3.5 released
- WordPress-Nginx tutorials
Hello,
With wordpress 3.5 comes some pretty drastic changes with media file handling. More specifically, the Upload file path has changed completely in 3.5 as can be found here: http://codex.wordpress.org/Multisite_Network_Administration#Uploaded_File_Path
Is there any chance of you updating your guides to reflect these changes? I’m extremely new to nginx and would hate to have to go back to apache or use an older version of wordpress because of not knowing nginx well enough to adapt.
Thanks for your consideration.
Hi Chris,
I have answered this here – https://rtcamp.com/support/topic/nginx-subdomain-multi-site-w3-total-cache-wordpress3-5/
In short, you can ignore changes if you are in hurry.
Which line were you referring to? Why would my nginx conf change if I’m using an A record vs. a CNAME?
Thanks, great articles!
I am referring to line:
By default it is off but in case you face any issue, you need to uncomment that line. More info about server_name_in_redirect is here.
Regarding A-records v/s CNAME…
First, there was a typo. I wanted to say that you need to make changes for domain-mapping to work. The change was a line as mentioned above. So domain-mapping may affect your config. Not sure if you need to change config while switching from A-records to CNAME.
If you are using CNAME records + domain-mapping, can you please share your nginx config?
I never used CNAME records as they involve 2 lookups but there are valid cases to use CNAME records.
Anyway, I corrected line which caused confusion. Thanks.
I’m having some issues since I can’t use the same vps for hosting other websites, as soon as I create another “virtual server” on nginx*, WordPress MU + Domain Mapping stops working (500 error).
I’m really confused because if I set it, the new server works, but everything else, including all the others domain that I’m managing trough the DM plugin, also stops working.
*something being really simple like:
server {
server_name a_different_domain.tld;
root /some/other/place;
try_files $uri $uri/ /index.php$is_args?args;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_passs unix:/var/run/php-fpm/another_socket.sock;
}
My original nginx.conf (the one that’s hosting the network) is similar:
server {
server_name mydomain.tld *.mydomain.tld;
server_name_in_redirect off;
root /some/place;
try_files $uri $uri/ /index.php$is_args?args;
include file_with_confs.conf;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_passs unix:/var/run/php-fpm/my_socket.sock;
}
Hi, will this tutorial work on WP 3.7?
I’m having a problem with a similar setup!
Everything worsks fine in the Primary Blog, but all others give me 404 on CSS files, even the Network site!
What could I be missing?
Try copying our config as it is.
If that doesn’t work, you can share your config and other details like 404-links in our support forum – https://rtcamp.com/support/forum/wordpress-nginx/
We will try to debug it.
I found the problem, it was actually all static files, including pics, because those blogs are using the /uploads dir, not “/files”, the css was my misconfiguration… I was using hotlink protection and forgot to add the 2 of the blogs, to the allowed referrers!
Btw do you have any hints on SSL w/ W3 Total Cache? That’s my next step… The idea would be to rewrite all to SSL… not sure if this part still works though:
# Use cached or actual file if they exists, otherwise pass request to WordPress
location / {
try_files /wp-content/cache/page_enhanced${cache_uri}_index.html $uri $uri/ /index.php?$args;
}
*sorry in my case I’m using:
# Use cached or actual file if they exists, otherwise pass request to WordPress
location / {
try_files /wp-content/cache/page_enhanced/${host}${cache_uri}_index.html $uri $uri/ /index.php?$args;
}
I wonder if I should add $scheme too?
I think your original issue is solved.
Please use our free support-forum https://rtcamp.com/support/forum/wordpress-nginx/ for other issues.
I used easy engine to install multisite subdomain with w3 and thinks it works as expected.
What I would want to accomplish now is that when someone visits farak.in with A record pointing to the wordpress VPS, then url in the address bar does NOT change from farak.in to farak.sachinkundu.name. I think the default behavior is not to change the address but there must be some rewrite rule which I am not able to find.
The response headers returned when visiting farak.in is
Request URL:http://farak.in/
Request Method:GET
Status Code:301 Moved Permanently
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
DNT:1
Host:farak.in
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.72 Safari/537.36
Response Headers
Connection:keep-alive
Content-Type:text/html; charset=UTF-8
Date:Wed, 15 Jan 2014 09:09:11 GMT
Location:http://farak.sachinkundu.name/
Server:nginx
Transfer-Encoding:chunked
X-Pingback:http://farak.sachinkundu.name/xmlrpc.php
I think you want farak.sachinkundu.name and farak.in both to return farak.sachinkundu.name in address bar.
In domain-mapping plugin there is a “Primary” checkbox. It might work on your end.
Other way is to create a nginx config for farak.in on server and redirect all requests to that domain to farak.sachinkundu.name
A tiny comment on the fact that the server directive needs to be included in the http directive of the config file.
Also, I am now getting 500 server errors for any files that I have attached to the site which do not map properly. This happened with a logo that I set in the theme preferences.
The URL to that logo looks like
http://subdomain.mainsite.com
but when I preview the site I am mapped tomappeddomain.com
which cannot load thehttp://subdomain.mainsite.com/files/logo.png
. Is there anything I may be overlooking?Thanks
A.
Sorry. I am not able to understand your problem.
server directive cannot be included in http. These articles are part of series – https://rtcamp.com/wordpress-nginx/tutorials/ and follows some conventions https://rtcamp.com/wordpress-nginx/tutorials/conventions/