KBeezie

There's no place like ::1

Menu
  • Home
  • Start Here
  • Security Series
  • About

Nginx Configuration Examples

2011/03/31 in Archived

⚠️  Archived — Originally published March 2011

These configuration examples target WordPress + W3 Total Cache minify rules, ZenPhoto, and Drupal 7 — all from the Nginx 0.8.x/1.0.x era. The manual fastcgi_param declarations listed here are now handled automatically by modern distributions' fastcgi_params include, and the TCP-based fastcgi_pass 127.0.0.1:9000 has been superseded by Unix sockets in current PHP-FPM defaults. The include php.conf / include drop.conf pattern still works, but the specific CMS configurations are frozen in 2011. Content is preserved for historical reference only.

Here are a number of Nginx configurations for common scenarios that should help make things easier to get started with. This page will grow as needed.

A quick and easy starter example

First one is for most of you fly-by and cut-and-paste type of people. If you're using a typical /sites-enabled/default type of configuration, replace the content of that file with this. Make sure to change the root path and your php port/path if it differs.


server {
	#.domain.com will match both domain.com and anything.domain.com
	server_name .example.com;

	#It is best to place the root of the server block at the server level, and not the location level
	#any location block path will be relative to this root. 
	root /usr/local/www/example.com;

	# It's always good to set logs, note however you cannot turn off the error log
	# setting error_log off; will simply create a file called 'off'.
	access_log /var/log/nginx/example.access.log;
	error_log /var/log/nginx/example.error.log;

	# This can also go in the http { } level
	index index.html index.htm index.php;

	location / { 
		# if you're just using wordpress and don't want extra rewrites
		# then replace the word @rewrites with /index.php
		try_files $uri $uri/ @rewrites;
	}
	
	location @rewrites {
		# Can put some of your own rewrite rules in here
		# for example rewrite ^/~(.*)/(.*)/? /users/$1/$2 last;
		# If nothing matches we'll just send it to /index.php
		rewrite ^ /index.php last;
	}

	# This block will catch static file requests, such as images, css, js
	# The ?: prefix is a 'non-capturing' mark, meaning we do not require
	# the pattern to be captured into $1 which should help improve performance
	location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
		# Some basic cache-control for static files to be sent to the browser
		expires max;
		add_header Pragma public;
		add_header Cache-Control "public, must-revalidate, proxy-revalidate";
	}

	# remove the robots line if you want to use wordpress' virtual robots.txt
	location = /robots.txt { access_log off; log_not_found off; }
	location = /favicon.ico { access_log off; log_not_found off; }	

	# this prevents hidden files (beginning with a period) from being served
	location ~ /\. { access_log off; log_not_found off; deny all; }

	location ~ \.php {
 	fastcgi_param QUERY_STRING $query_string;
 	fastcgi_param REQUEST_METHOD $request_method;
	fastcgi_param CONTENT_TYPE $content_type;
	fastcgi_param CONTENT_LENGTH $content_length;

	fastcgi_param SCRIPT_NAME $fastcgi_script_name;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	fastcgi_param REQUEST_URI $request_uri;
	fastcgi_param DOCUMENT_URI $document_uri;
	fastcgi_param DOCUMENT_ROOT $document_root;
	fastcgi_param SERVER_PROTOCOL $server_protocol;

 	fastcgi_param GATEWAY_INTERFACE CGI/1.1;
	fastcgi_param SERVER_SOFTWARE nginx;

 	fastcgi_param REMOTE_ADDR $remote_addr;
	fastcgi_param REMOTE_PORT $remote_port;
	fastcgi_param SERVER_ADDR $server_addr;
	fastcgi_param SERVER_PORT $server_port;
	fastcgi_param SERVER_NAME $server_name;

	 fastcgi_pass 127.0.0.1:9000;
	}
}

As for the rest of you, read on for some more goodies and other configuration examples.

Making the PHP inclusion easier

For the purpose of PHP I've created a php.conf in the same folder with nginx.conf, this file DOES NOT go into the same folder as your virtual host configuration for example if nginx.conf is in /etc/nginx/ , then php.conf goes into /etc/nginx/ not /etc/nginx/sites-enabled/.

If you are not using PHP-FPM, you really should be as opposed to the old spawn-fcgi or php-cgi methods. For debian lenny/squeeze dotdeb makes php5-fpm available, FreeBSD already includes it in the PHP 5.2 and 5.3 ports.


location ~ \.php {
	#for security reasons the next line is highly encouraged
	try_files $uri =404;

	fastcgi_param QUERY_STRING $query_string;
	fastcgi_param REQUEST_METHOD $request_method;
	fastcgi_param CONTENT_TYPE $content_type;
	fastcgi_param CONTENT_LENGTH $content_length;

	fastcgi_param SCRIPT_NAME $fastcgi_script_name;

	#if the next line in yours still contains $document_root
	#consider switching to $request_filename provides
	#better support for directives such as alias
	fastcgi_param SCRIPT_FILENAME $request_filename;

	fastcgi_param REQUEST_URI $request_uri;
	fastcgi_param DOCUMENT_URI $document_uri;
	fastcgi_param DOCUMENT_ROOT $document_root;
	fastcgi_param SERVER_PROTOCOL $server_protocol;

	fastcgi_param GATEWAY_INTERFACE CGI/1.1;
	fastcgi_param SERVER_SOFTWARE nginx;

	fastcgi_param REMOTE_ADDR $remote_addr;
	fastcgi_param REMOTE_PORT $remote_port;
	fastcgi_param SERVER_ADDR $server_addr;
	fastcgi_param SERVER_PORT $server_port;
	fastcgi_param SERVER_NAME $server_name;

	#If using a unix socket...
	#fastcgi_pass unix:/tmp/php5-fpm.sock;

	#If using a TCP connection...
	fastcgi_pass 127.0.0.1:9000;
}

I prefer to use a unix socket, it cuts out the TCP overhead, and increases security since file-based permissions are stronger. In php-fpm.conf you can change the listen line to /tmp/php5-fpm.sock, and should uncomment the listen.owner, listen.group and listen.mode lines.

REMEMBER: Set cgi.fix_pathinfo to 0 in the php.ini when using Nginx with PHP-FPM/FastCGI, otherwise something as simple as /forum/avatars/user2.jpg/index.php could be used to execute an uploaded php script hidden as an image.

Path_Info
If you must use PATH_INFO and PATH_TRANSLATED then add the following within your location block above (make sure $ does not exist after \.php or /index.php/some/path/ will not match):

	fastcgi_split_path_info ^(.+\.php)(/.+)$;
	fastcgi_param PATH_INFO $fastcgi_path_info;
	fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

It is advised however to update your script to use REQUEST_URI instead.

Optional Config - Drop

You can also have a file called drop.conf in the same folder with nginx.conf with the following:

	location = /robots.txt { access_log off; log_not_found off; }
	location = /favicon.ico { access_log off; log_not_found off; }	
	location ~ /\. { access_log off; log_not_found off; deny all; }
	location ~ ~$ { access_log off; log_not_found off; deny all; }

Using include drop.conf; at the end of your server block will include these. The first two simply turn off access logs and prevents logging an error if robots.txt and favicon.ico are not found, which is something a lot of browsers ask for. Wordpress typically uses a virtual robots.txt so you may omit the first line if needed so that the request is passed back to wordpress.

The third line prevents nginx from serving any hidden unix/linux files, basically any request beginning with a period.

And the forth line is mainly for people who use vim, or any other command line editor that creates a backup copy of a file being worked on with a file name ending in ~. Hiding this prevents someone from accessing a backup copy of a file you have been working on.

  • ← Previous
  • 1
  • 2
  • 3
  • 4
  • Next →
Tags: archived, nginx, wordpress, drupal
©2026 Karl Blessing | Disclaimer | Privacy Notice