I bought a Digital Ocean server and a Forge subscription because of one thing: I wanted to set up a new dev environment for all the projects I’m working on at Form Agenda. Since the majority of demo-sites I’m setting up are running on WordPress, the obvious choice would be to install a WordPress Multisite, with subdirectory demo-sites, on the new, fast server and run all the demo-sites out of a single installation. Manageable. Or so you would think.
I ran into an issue that many, many people have had before: Redirect loop when trying to access a sub-site – Shit.
The multisite is set up with subdirectory in mind, so I could create a yo.matiasvad.com/subsite1, yo.matiasvad.com/subsite2 per demo, and keep it separate from my old demo-structure (matiasvad.com/yo/subsite1).
Nginx is the (w/s)inner – Fixing the redirect loop!
When you start up a new server through Forge, and install WordPress directly through it, everything is set up for you; Nginx, MySQL and whatever else is needed – Sweet, you don’t have to worry about anything. But the default nginx config isn’t really set up for a WordPress Multisite.
After a week or so looking into the issue, trying different solutions, I finally found a simple nginx config that did the job!
Here’s the working nginx config.
server {
##DM - uncomment following line for domain mapping
#listen 80 default_server;
server_name yourdomain.com;
##DM - uncomment following line for domain mapping
#server_name_in_redirect off;
# FORGE SSL (DO NOT REMOVE!)
# ssl on;
# ssl_certificate;
# ssl_certificate_key;
access_log /var/log/nginx/yourdomain.com.access.log;
error_log /var/log/nginx/yourdomain.com.error.log;
root /home/forge/yourdomain.com;
index index.php;
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^(/[^/]+)?(/wp-.*) $2 last;
rewrite ^(/[^/]+)?(/.*\.php) $2 last;
}
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/${host}${cache_uri}_index.html $uri $uri/ /index.php?$args ;
}
location ~ \.php$ {
try_files $uri /index.php;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
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; }
}
And now the multisite setup is not causing a redirect loop anymore!
If you have any questions about Forge, please, feel free to ask in the comments, or ping me directly @matiasvad – It’s an awesome service, and I can only recommend it! I’m also open to suggestions to the nginx-config I posted. Anything to make it better is appreciated!