My Nginx Configuration

I’m creating this page on popular request, as I’ve had to paste my configuration for people a number of times especially on IRC. Below is an example configuration of how is setup with some comments.

My primary nginx.conf file located in /conf

# Normally you don't want to run a webserver as root
# so you set www-data (debian/ubuntu) or nobody (centos/rhel)
# you'll want to make sure your web root is owned by www-data group
user www-data;
# 4 worker processes is usually sufficient for a webserver serving
# both static files and passing dynamic requests back to apache, fastcgi or an app server
worker_processes     4;
# normally you leave this at the default of 1024
events {
    worker_connections  1024;
http {
    # General Settings
    gzip  on;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay off;
    server_tokens off;
    include mime.types;
    keepalive_timeout 5;
    default_type  application/octet-stream;
    # If we set index here, we won't have to anywhere else
    index index.php index.html index.htm;
    # I prefer nginx to show the errors than "No Input Files Specified"
    # If you're using wordpress you want to turn this off so Wordpress
    # Shows the error. You can turn it off at the server or location level.
    # ONLY works if the server block has error pages defined for 4xx/5xx
    fastcgi_intercept_errors on;
    # We don't want someone to visit a default site via IP
    # So we catch all non-defined Hosts or blank hosts here
    # the default listen will cause this server block to be used
    # when no matching hostname can be found in other server blocks
    server {
	# use default instead for nginx 0.7.x, default_server for 0.8.x+
	listen 80 default_server;
	# if no listen is specified, all IPv4 interfaces on port 80 are listened to
	# to listen on both IPv4 and IPv6 as well, listen [::] and must be specified. 
	server_name _;
	return 444; 
    include sites-enabled/*;

A site configuration located inside the /conf/sites_enabled folder

# Wordpress Example
server {
	# The usual names, starting with the base, then www., subdomains or *. wild cards.
	# Keep a root path in the server level, this will help automatically fill
	# Information for stuff like FastCGI Parameters
	root html/;
	# You can set access and error logs at http, server and location level
	# Likewise means you turn them off at specific locations
	access_log logs/kbeezie.access.log;
	error_log logs/kbeezie.error.log;
	# For my wordpress configuration, I prefer try_files
	# It will try for static file, folder, then falls back to index.php
	# The wordpress index.php is capable of parsing the URI automatically
	location / { try_files $uri $uri/ /index.php; }
	# Where I turned off intercept errors for WordPress
	fastcgi_intercept_errors off;
	# Includes my PHP location block and parameters
	include php;
	# My all in one settings to hide stuff like .invisible files
	# or turn off access/error logs to favicon/robots.txt
	include drop;
# Proxy_Pass example (backend server, or in my case Python App)
# For Python WSGI or Ruby/Rails you can check out 
server {
	# You can choose to turn remove this if you wish to
	# See requested URIs
	access_log off;
	# If your application returns any erorrs it can be logged by nginx
	# However if the application fails, or is not stated you'll see
	error_log logs/python.error.log;
	# I usually run my apps from base domains or subdomains rather than
	# folders, though it is possible. 
	# a root definition where you can store static files
	# if not served by the application
	root html/python-static/;
	# Since we have a static root defined, we can check
	# for static files there, otherwise goes to the backend
	location / { try_files $uri $uri/ @backend; }
	# The backend for either backend servers or apps
	location @backend {
		# Lets the app/backend know the visitor's IP
		# otherwise shows
		proxy_set_header X-Real-IP  $remote_addr;
		proxy_set_header X-Forwarded-For $remote_addr;
		# Some app servers need to be made aware of the hostname
		proxy_set_header Host $host;
		# example on how to connect to a unix socket
		proxy_pass	http://unix:/opt/apps/ipn/ipn.sock:/;
		# Example via TCP location of the backend server
		# proxy_pass;
	# you could copy drop into drop_deny to outright deny favicon and robots.txt for apps
	include drop;

A single file called php located in the /conf folder, using this method makes it easy to enable
php on a per-server basis.

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;
	# I use a socket for php, tends to be faster
	# for TCP just use
	fastcgi_pass   unix:/opt/php-fpm.sock;
	# Not normally needed for wordpress since you are
	# sending everything to index.php in try_files
	# this tells it to use index.php when the url
	# ends in a trailing slash such as
	fastcgi_index  index.php;

A file called drop in the /conf folder, including this into your server configuration will drop/block
common files you do not wish to be exposed to the web.

# Most sites won't have configured favicon or robots.txt
# and since its always grabbed, turn it off in access log
# and turn off it's not-found error in the error log
location = /favicon.ico { access_log off; log_not_found off; }	
location = /robots.txt { access_log off; log_not_found off; }
# Rather than just denying .ht* in the config, why not deny
# access to all .invisible files 
location ~ /\. { deny  all; access_log off; log_not_found off; }

Further comments will be appended here.

Comments are closed.