Running WordPress on Nginx
WordPress is designed to run on Apache and use rewrite rules stuffed into an .htaccess
file, but it’s pretty simple to set up WordPress to run using Nginx instead. I’ll share a sample configuration here that I’ve been using for the last two years.
Why?
Why would you want to do this? If you’re not familiar with Nginx, it’s a great lightweight webserver capable of handling high traffic under load much better than Apache or Lighttpd (another lightweight webserver). It’s written by Igor Sysoev for Rambler (sort of the Russian equivalent of Yahoo!), and the code is very well organized. Once you get to know it, you’ll probably prefer its nested configuration syntax to Apache’s as well — it lets you do more with less typing, so config files are more compact and easier to read.
If you’re reading this and going “I thought I heard that WordPress was already using Nginx,” what you’re probably thinking of is WordPress.com recently switching to using Nginx as a frontend load-balancing HTTP proxy or to serve static images and files instead of Lighttpd. Those are both excellent use cases for Nginx, but what this configuration will do is run your WordPress site with Nginx as its primary webserver (no Apache!), connecting to PHP via FastCGI.
Speaking of FastCGI, if you aren’t already running the Nginx/PHP-via-FCGI combo, here’s how to do it. You’ll need your PHP compiled as CGI with the --enable-fastcgi
option (or use your distro’s PHP/CGI package).
Configuration
OK, enough blabber, on to the config. It’s actually really simple!
To enable “pretty” URLs, WordPress normally creates an Apache .htaccess
file in its root directory containing a basic mod_rewrite
rule to simply send all requests not matching a file or directory to WordPress’ root index.php
:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
The corresponding Nginx equivalent is:
if (!-e $request_filename) {
rewrite ^.* /index.php break;
}
Now, Nginx doesn’t support .htaccess
files. This is actually not a bad thing, because while .htaccess
can be handy with shared hosting, it’s a performance dog. This is because, when enabled, Apache scans the filesystem looking for these files on every request — so if you’re running your own Apache, keep all your configuration in /etc
where it belongs and set AllowOverride None
! So, Nginx makes you do what you should have been doing already, and put this rewrite rule in the main server config file or virtual host config file for your site.
So, putting it all together, here’s the site configuration for www.example.com:
server {
listen www.example.com:80;
server_name www.example.com;
charset utf-8;
error_log /www/www.example.com/log/error.log;
access_log /www/www.example.com/log/access.log main;
root /www/www.example.com/htdocs;
include /etc/nginx/fastcgi.conf;
fastcgi_index index.php;
# Send *.php to PHP FastCGI on :9001
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9001;
}
location / {
index index.html index.php;
# URLs that don't exist go to WordPress /index.php PHP FastCGI
if (!-e $request_filename) {
rewrite ^.* /index.php break;
fastcgi_pass 127.0.0.1:9001;
}
}
}
Pretty simple! And FYI, the /etc/nginx/fastcgi.conf
I’m including here is essentially this one.