⚠️ Archived — Originally published March 2010
These personal configuration files are from the Nginx 0.7.x/0.8.x era on FreeBSD. The worker_processes 4 and tcp_nodelay off settings are no longer optimal defaults, and the fastcgi_intercept_errors behavior described here works differently in modern Nginx. The PHP-FPM config references Unix sockets that newer PHP packages configure differently. Content is preserved for historical reference only.
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 kbeezie.com 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 0.0.0.0 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.
server_name kbeezie.com www.kbeezie.com;
# Keep a root path in the server level, this will help automatically fill
# Information for stuff like FastCGI Parameters
root html/kbeezie.com;
# 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
# http://kbeezie.com/view/using-python-nginx-passenger/
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
# 502 BAD GATEWAY
error_log logs/python.error.log;
# I usually run my apps from base domains or subdomains rather than
# folders, though it is possible.
server_name apps.mydomain.com;
# 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 127.0.0.1
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 http://127.0.0.1:8008;
}
# 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 127.0.0.1:port#
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 domain.com/
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.