Nginx configuration for WordPress
This is a nginx configuration for running WordPress.
It makes use of nested locations with named capture groups instead of fastcgi_split_path_info.
This example configuration assumes that the site is called
example.com. Change accordingly to reflect your server setup.
Filtering of invalid HTTP
Access to install files, like
install.php,is protected using HTTP Basic Auth.
Protection of all the internal directories, like version control repositories and the
readmefile(s) that come with WP or an external plugin.
Faster and more secure handling of PHP FastCGI by Nginx using named groups in regular expressions instead of using fastcgi_split_path_info. Requires Nginx version ≥ 0.8.25.
Compatible with the WordPress plugin wp-super-cache for serving static pages to anonymous users.
Upload Progress support.
Possibility of using Apache as a backend for dealing with PHP. Meaning using Nginx as reverse proxy.
Operating system open files cache for static assets like CSS and JS, for example.
Note that for mp4 streaming to work properly, with seeking enabled, you must use a compatible player and run a Nginx version greater or equal to 1.1.3 for the development branch and 1.0.7 for the stable branch.
Basic Auth for access to restricted files like install.php
install.php and the WordPress
readme.html are protected using
Basic Auth. The readme file discloses the version number of
install.php, but any PHP file that has install.php
as the ending is protected. This way if, for example, there's a
permission problem with
wp-config.php and WP can't read the file
it will invoke
install.php since it assumes that if no specific
configuration information is available then the site must not yet
be installed. Now imagine that this happens on your site and that
someone stumbles on the
install.php? If not protected by the
Basic Auth, information disclosure would be the least potential
You have to create the
.htpasswd-users file with the user(s) and
password(s). For that, if you're on Debian or any of its
derivatives like Ubuntu you need the
package installed. Then create your password file by issuing:
htpasswd -d -b -c .htpasswd-users <user> <password>
You should delete this command from your shell history
history -d <command number> or alternatively
-b switch, then you'll be prompted for the password.
This creates the file (there's a
-c switch). For adding
additional users omit the
Of course you can rename the password file to whatever you want,
then accordingly change its name in the virtual host config
Nginx as a Reverse Proxy: Proxying to Apache for PHP
If you absolutely need to use the rather bad habit of
deploying web apps relying on
.htaccess, or you just want to use
Nginx as a reverse proxy. The config allows you to do so. Note that
this provides some benefits over using only Apache, since Nginx is
much faster than Apache. Furthermore you can use the proxy cache
and/or use Nginx as a load balancer.
IPv6 and IPv4
The configuration of the example vhosts uses separate sockets for
IPv6 and IPv4. This way is simpler for those not (yet) having IPv6
support to disable it by commenting out the
directive with the
Note that the IPv6 address uses an IP stolen from the IPv6 Wikipedia page. You must replace the indicated address by your address.
Move the old
Clone the git repository from github:
git clone https://github.com/perusio/wordpress-nginx.git
sites-available/example.com.confconfiguration file to suit your requirements. Namely replacing
example.comwith your domain.
Setup the PHP handling method. It can be:
Upstream HTTP server like Apache with mod_php. To use this method comment out the
include upstream_phpcgi.conf;line in
nginx.confand uncomment the lines:
include reverse_proxy.conf; include upstream_phpapache.conf;
Now you must set the proper address and port for your backend(s) in the
upstream_phpapache.conf. By default it assumes the loopback
127.0.0.1interface on port
8080. Adjust accordingly to reflect your setup.
Comment out all
fastcgi_passdirectives in either
drupal_boost_drush.conf, depending which config layout you're using. Uncomment out all the
proxy_passdirectives. They have a comment around them, stating these instructions.
FastCGI process using php-cgi. In this case an init script is required. This is how the server is configured out of the box. It uses UNIX sockets. You can use TCP sockets if you prefer.
PHP FPM, this requires you to configure your fpm setup, in Debian/Ubuntu this is done in the
Look here for an example configuration of
Check that the socket is properly created and is listening. This can be done with
netstat, like this for UNIX sockets:
netstat --unix -l
And like this for TCP sockets:
netstat -t -l
It should display the PHP CGI socket.
Note that the default socket type is UNIX and the config assumes it to be listening on
unix:/tmp/php-cgi/php-cgi.socket, if using the
php-cgi, or in
php-fpmand that you should change to reflect your setup by editing
/etc/nginx/sites-enableddirectory and enable the virtual host using one of the methods described below.
Note that if you're using the nginx_ensite script described below it creates the
/etc/nginx/sites-enableddirectory if it doesn't exist the first time you run it for enabling a site.
Check that WordPress is working by visiting the configured site in your browser.
Enabling and Disabling Virtual Hosts
I've created a shell script nginx_ensite that lives here on github for quick enabling and disabling of virtual hosts.
If you're not using that script then you have to manually
create the symlinks from
the virtual hosts configured in
sites-enabled will be available
for Nginx to serve.
Acessing the php-fpm status and ping pages
You can get the
status and a ping pages
for the running instance of
php-fpm. There's a
php_fpm_status.conf file with the configuration for both
the status page at
the ping page at
For obvious reasons these pages are acessed only from a given set of IP addresses. In the suggested configuration only from localhost and non-routable IPs of the 192.168.1.0 network.
The allowed hosts are defined in a geo block in file
php_fpm_status_allowed_hosts.conf. You should edit the predefined IP addresses to suit your setup.
To enable the status and ping pages uncomment the line in the
example.com.confvirtual host configuration file.
Getting the latest Nginx packaged for Debian or Ubuntu
It may work or not on Ubuntu. Since Ubuntu seems to appreciate more finding semi-witty names for their releases instead of making clear what's the status of the software included. Is it stable? Is it testing? Is it unstable? The package may work with your currently installed environment or not. I don't have the faintest idea which release to advise. So you're on your own. Generally the APT machinery will sort out for you any dependencies issues that might exist.
My other Nginx configs on github
Securing your PHP configuration
I have created a small shell script that parses your
sets a sane environment, be it for development or
Grab it here.
Thanks to Burçe Boran for helping me sort out the issues of the configuration for supercache 0.9.9.9.