Installing Wordpress on NGINX via php-fpm
30 Dec 2011This is a short tutorial on how to install php-fpm on debian squeeze and how to configure nginx so it will serve a wordpress installation.
Install php-fpm by adding a new apt source:
sudo echo "deb http://packages.dotdeb.org stable all" >> /etc/apt/sources.list apt-get update
Apt will probably complain about a missing key for the just added repository. This can be fixed by adding the key to apts keyring. Please make sure that you get the right key and compare the fingerprints.
gpg --export <PUBLIC_KEY> | apt-key add -
Now install php-fpm
apt-get update apt-get install php5-fpm php5-suhosin php5-mysql
By default php-fpm listens on http://127.0.0.1:9000. Since we are on a unix system, we like to make use of sockets. Open fpm pool configuration and search for the listen directive. Then adapt it to your needs.
# /etc/php5/fpm/pool.d/www.conf listen = /tmp/php-fpm.sock
Add an upstream server for php to nginx.conf so it is available for all configurations:
# /etc/nginx/nginx.conf # Upstream to abstract backend connection(s) for PHP. upstream php { server unix:/tmp/php-fpm.sock # or whatever you configured php-fpm to listen to }
Add these global configurations for nginx to /etc/nginx/global
# Global restrictions configuration file. | |
# Designed to be included in any server {} block.</p> | |
location = /favicon.ico { | |
log_not_found off; | |
access_log off; | |
} | |
location = /robots.txt { | |
allow all; | |
log_not_found off; | |
access_log off; | |
} | |
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). | |
location ~ /\. { | |
deny all; | |
access_log off; | |
log_not_found off; | |
} |
# WordPress multisite subdirectory rules. | |
# Designed to be included in any server {} block. | |
# This order might seem weird - this is attempted to match last if rules below fail. | |
# http://wiki.nginx.org/HttpCoreModule | |
location / { | |
try_files $uri $uri/ /index.php?$args; | |
} | |
# Add trailing slash to */wp-admin requests. | |
rewrite /wp-admin$ $scheme://$host$uri/ permanent; | |
# Directives to send expires headers and turn off 404 error logging. | |
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { | |
expires 24h; | |
log_not_found off; | |
} | |
# Pass uploaded files to wp-includes/ms-files.php. | |
rewrite /files/$ /index.php last; | |
# For multisite: Use a caching plugin/script that creates symlinks to the correct subdirectory structure to get some performance gains. | |
set $cachetest "$document_root/wp-content/cache/ms-filemap/${host}${uri}"; | |
if ($uri ~ /$) { | |
set $cachetest ""; | |
} | |
if (-f $cachetest) { | |
# Rewrites the URI and stops rewrite processing so it doesn't start over and attempt to pass it to the next rule. | |
rewrite ^ /wp-content/cache/ms-filemap/${host}${uri} break; | |
} | |
if ($uri !~ wp-content/plugins) { | |
rewrite /files/(.+)$ /wp-includes/ms-files.php?file=$1 last; | |
} | |
# Uncomment one of the lines below for the appropriate caching plugin (if used). | |
# include global/wordpress-ms-subdir-wp-super-cache.conf; | |
# include global/wordpress-ms-subdir-w3-total-cache.conf; | |
# Rewrite multisite '.../wp-.*' and '.../*.php'. | |
if (!-e $request_filename) { | |
rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last; | |
rewrite ^/[_0-9a-zA-Z-]+.*(/wp-admin/.*\.php)$ $1 last; | |
rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last; | |
} | |
# Pass all .php files onto a php-fpm/php-fcgi server. | |
location ~ \.php$ { | |
# Zero-day exploit defense. | |
# http://forum.nginx.org/read.php?2,88845,page=3 | |
# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi. | |
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked. | |
try_files $uri =404; | |
fastcgi_split_path_info ^(.+\.php)(/.+)$; | |
include fastcgi_params; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
# fastcgi_intercept_errors on; | |
fastcgi_pass php; | |
} |
Download wordpress and unpack
cd /var/www/mydomain wget http://wordpress.org/latest.tar.gz tar xzf latest.tar.gz
All that is needed now is the nginx configuration
server { listen 80; server_name mydomain.com; access_log /var/log/nginx/mydomain.access_log; error_log /var/log/nginx/mydomain.error_log; index index.php index.html index.htm; root /var/www/mydomain/wordpress; include global/restrictions.conf; include global/wordpress-ms-subdir.conf; }