Include files
Don't be shy in splitting up your main
nginx.conf file into several smaller files. Your co-workers will be
grateful. A structure that has been working for me is to have one file
where I define my upstream pools, one file where I define locations that
point to upstream pools, and one file where I define servers that
handle those locations.
Examples:
upstreams.conf
upstream cluster1 {
fair;
server app01:7060;
server app01:7061;
server app02:7060;
server app02:7061;
}
upstream cluster2 {
fair;
server app01:7071;
server app01:7072;
server app02:7071;
server app02:7072;
}
locations.conf
location / {
root /var/www;
include cache-control.conf;
index index.html index.htm;
}
location /services/service1 {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Pragma "no-cache";
proxy_pass http://cluster1/;
}
location /services/service2 {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Pragma "no-cache";
proxy_pass http://cluster2/service2;
}
servers.conf
server {
listen 80;
include locations.conf;
}
At
this point, your nginx.conf looks very clean and simple (you can still
split it into more include files, by separating for example the gzip
configuration options into their own file etc.)
nginx.conf
worker_processes 4;
worker_rlimit_nofile 10240;
events {
worker_connections 10240;
use epoll;
}
http {
include upstreams.conf;
include mime.types;
default_type application/octet-stream;
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time';
access_log /usr/local/nginx/logs/access.log custom;
proxy_buffering off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript
application/x-javascript application/xml application/xml+rss
image/svg+xml application/x-font-ttf application/vnd.ms-fontobject;
gzip_disable "MSIE [1-6]\.";
# proxy cache config
proxy_cache_path /mnt/nginx_cache levels=1:2
keys_zone=one:10m
inactive=7d max_size=10g;
proxy_temp_path /var/tmp/nginx_temp;
proxy_next_upstream error;
include servers.conf;
}
This nginx.conf file is fairly vanilla in terms of the configuration options I used, but it's worth pointing some of them out.
Multiple worker processes
This is useful when you're running nginx on a multi-core box. Example:
worker_processes 4;
Increased number of file descriptors
This
is useful for nginx instances that get hit by very high traffic. You
want to increase the maximum number of file descriptors that nginx can
use (the default on most Unix systems is 1024; run 'ulimit -n' to see
the value on your system). Example:
worker_rlimit_nofile 10240;
Custom logging
See
the log_format and access_log directives above. In particular, the
"$http_x_forwarded_for" value is useful if nginx is behind another load
balancer, and "$request_time" is useful to see the time taken by nginx
when processing a request.
CompressionThis is useful when you want to compress certain types of content sent back to the client. Examples:
gzip_proxied expired no-cache no-store private auth;
gzip_types
text/plain text/css text/xml text/javascript
application/x-javascript application/xml application/xml+rss
image/svg+xml application/x-font-ttf application/vnd.ms-fontobject;
gzip_disable "MSIE [1-6]\.";
Proxy options
These are options you can set per location. Examples:
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Pragma "no-cache";
Most
of these options have to do with setting custome HTTP headers (in
particular 'no-cache' in case you don't want to cache anything related
to that particular location)
Proxy cache
Nginx can be used as a caching server.
You need to define a proxy_cache_path and a proxy_temp_path under your
http directive, then use them in the locations you want to cache.
proxy_cache_path /mnt/nginx_cache levels=1:2
inactive=7d max_size=10g;
proxy_temp_path /var/tmp/nginx_temp;
In the location you want to cache, you would add something like this:
proxy_cache one;
proxy_cache_key mylocation.$request_uri;
proxy_cache_valid 200 302 304 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
HTTP caching options
Many
times you want to cache certain types of content and not others. You
can specify your caching rules in a file that you include in your root
location:
location / {
root /var/www;
include cache-control.conf;
index index.html index.htm;
}
You
can specify different expire headers and cache options based on the
request URI. Examples (inside cache-control.conf in my case)
# default cache 1 day
expires +1d;
if ($request_uri ~* "^/services/.*$") {
expires +0d;
add_header Pragma "no-cache";
}
if ($request_uri ~* "^/(index.html)?$") {
expires +1h;
}
SSL
All
you need to do here is to define another server in servers.conf, and
have it include the locations you need (which can be the same ones
handled by the server on port 80 for example):
server {
server_name www.example.com;
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/ssl/cert.pem;
ssl_certificate_key /usr/local/nginx/ssl/cert.key;
include locations.conf;
}