Skip to content

Instantly share code, notes, and snippets.

@tompave

tompave/nginx.conf

Last active Nov 12, 2020
Embed
What would you like to do?
commented nginx.conf for Ruby on Rails
# A commented nginx configuration file for Ruby on Rails
#
# Author: Tommaso Pavese
# tommaso@pavese.me
# http://tommaso.pavese.me
#
# License: http://www.wtfpl.net/
#
#
# Tested with:
# Ubuntu 12.04
# nginx 1.4.1 - 1.4.7
# Rails 3.2 - 4.0
# Unicorn, Thin and Puma
#
#
# Docs:
# http://nginx.org/en/docs/
#
# Configuration measurement units:
# http://nginx.org/en/docs/syntax.html
#
# Each module can define its variables, the core ones:
# http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
#
#
# As reference, the official example for nginx + unicorn:
# https://github.com/defunkt/unicorn/blob/master/examples/nginx.conf
#
#
# In order to bind to port 80, the master process must be executed as root:
# $ sudo /usr/sbin/nginx -c /etc/nginx/nginx.conf
#
# How to execute the worker processes
user user_name group_name;
# A single worker is enough for load balancing and reverse proxing.
# However:
# Disk I/O can block an nginx worker (depends on disk read performance).
# If the server is serving a lot of static files (e.g. assets) it is
# a good idea to increase the number of worker processes.
worker_processes 1;
# The limit on the maximum number of open files for worker processes.
# "open files" is intended as UNIX open file descriptors.
# This overrides the limit set by the OS for the user the workers run as.
# Run `ulimit -a` in a shell to see the current limit.
worker_rlimit_nofile 2048;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# --------------------------------------------------------
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # "on" if nginx worker_processes > 1
use epoll; # best for Linux 2.6+ ("kqueue" for FreeBSD, OSX)
}
# --------------------------------------------------------
http {
# disables emitting nginx version in error messages
# and in the “Server” response header field
server_tokens off;
# MIME types
include /etc/nginx/mime.types;
# fallback MIME type if the client doesn't specify it.
default_type application/octet-stream;
# log
access_log /var/log/nginx/access.log combined;
# TCP settings
tcp_nopush on;
tcp_nodelay off;
# use unix sendfile()
sendfile on;
# gzip compression
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_vary on;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript application/x-javascript
application/javascript application/json
application/atom+xml;
# text/html is included by default
# According to the HTTP standard, headers with underscores are perfectly valid.
# However, nginx defaults to dropping headers containing underscores, as they
# might introduce ambiguities when mapping headers to CGI variables.
#
# Since this is not a problem with Ruby on Rails, we can safely enable them.
underscores_in_headers on;
# --------------------------------------------------------
# It's possible to organize the server configuration in different files.
#
# Typically, these site-specific files contain at least:
# - a server{} block
# - an upstream{} block
#
# The convention is to store configuration files in:
# /etc/nginx/sites-availbale/
#
# and then symlink them into:
# /etc/nginx/sites-enabled/
#
# with:
# $ ln -s /etc/nginx/sites-availbale/example.com.conf /etc/nginx/sites-enabled/example.com.conf
#
# After that, send a HUP signal to the nginx master to reload the configuration on the fly:
# $ sudo kill -HUP `cat /var/run/nginx.pid`
#
#
include /etc/nginx/sites-enabled/*;
# --------------------------------------------------------
# upstream destinations
#
# http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
#
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response.
# This happens when the Unicorn master nukes a single worker for timing out.
#
# Sockets can be opened at any location where the user has writing access,
# even inside the rails_root/tmp/sockets directory
#
# We can also use IP addresses and domain names, and mix them together.
#
# If more than one destination server is specified, the requests
# are distributed using a weighted round-robin balancing method.
#
# Important:
# Unicorn workers can all listen on the same Unix socket (or TCP port)
# at the same time.
# However, this might not be true for other servers.
# A cluster of Thins, for example, will require a Unix socket per process.
# Look at the second upstream block for an example.
# This works well with Unicorn (yes, even with several workers)
upstream rails_app_one {
server unix:/tmp/rails_app_one.sock fail_timeout=0;
}
# This will work with a cluster of 3 Thin servers
upstream rails_app_two {
server unix:/tmp/rails_app_two.0.sock fail_timeout=0;
server unix:/tmp/rails_app_two.1.sock fail_timeout=0;
server unix:/tmp/rails_app_two.2.sock fail_timeout=0;
}
# This is weird, but it would still work.
upstream rails_app_three {
server unix:/tmp/rails_app_three.sock fail_timeout=0;
server 192.168.0.7:8080 fail_timeout=0;
server 127.0.0.1:3000 weight=3 fail_timeout=0;
server backendworker.example.com weight=5 fail_timeout=0;
}
# --------------------------------------------------------
# servers
# This server listens to port 80 and 443, and is configured to accept
# both HTTP and HTTPS traffic on the same domain.
# The Rails app can then decide to enforce HTTPS on the whole application
# or only on specific controllers.
#
server {
# Only one server can use the 'default_server' and 'deferred' options.
listen 80 default_server deferred;
# http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
#
# Also accepts lists of names, wildcard characters and regular expressions.
# Make sure that they all match the SSL/TSL certificate, if using one.
# See the last server block for more examples.
server_name www.example.com;
# HTTPS
# http://nginx.org/en/docs/http/configuring_https_servers.html
#
# If the key has a passphrase, nginx will require it each time it will
# boot or restart (making automatic management impossible).
listen 443 ssl;
ssl_certificate /etc/nginx/sslfiles/example_com_chained.crt;
ssl_certificate_key /etc/nginx/sslfiles/example_com_ssl_nopf.key;
ssl_session_cache shared:example_ssl_cache:1m;
ssl_session_timeout 5m;
client_max_body_size 4G; # default 1M
keepalive_timeout 20s; # default 75s
root /var/www/example/current/public;
# http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
#
# Tries URIs in sequence until one is found.
# First we try to serve static files directly from nginx.
# The rails application is the last alternative.
#
# See comment block at the end of the file for detailed examples.
#
# /maintenance.html can be symlinked into public/ to stop requests
# before they reach the rails app (e.g. while updating the DB).
# When it does not exist (normally), it's quickly skipped.
#
try_files /maintenance.html $uri $uri/index.html $uri.html @rails_app;
# The location directory allows very creative configurations.
# http://nginx.org/en/docs/http/ngx_http_core_module.html#location
#
# This is just a named location to be used in try_files.
location @rails_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # the client IP
proxy_set_header X-Real-IP $remote_addr; # the client IP (again)
proxy_set_header X-Forwarded-Proto $scheme; # pass scheme (for HTTPS)
proxy_set_header Host $http_host; # the full host, for redirects within Rails
proxy_redirect off; # disable nginx redirect-rewrite logic
proxy_pass http://rails_app_one; # http is to be used even for https traffic
}
# Customize what html file should be served for different errors.
error_page 500 502 503 504 /500.html;
# This location block isn't strictly required, as '/500.html'
# can also be served by 'try_files $uri', above. Still, this
# location is more precise (thus has higher priority) and can
# be used to further customize the error response.
#
# location = /500.html { }
}
# A redirect from the naked domain to www
#
# This listens to port 80, thus it can't handle HTTPS traffic.
# (therefore, using $scheme instead of http is a bit useless)
#
# If the certificate is also compatible with the naked domain,
# then this server block can be improved by replicating here
# the SSL configuration of the main server.
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
# ----------------------------
# This server block features an efficient configuration
# to serve the pre-gzipped version of the static assets
server {
listen 80;
server_name .winter.is.coming.com
www.winteriscoming.com
*.winteriscoming.net;
client_max_body_size 4G;
keepalive_timeout 10s;
root /var/www/winteriscoming/current/public;
try_files $uri $uri/index.html $uri.html @rails_app;
error_page 500 502 503 504 /500.html;
location @rails_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://rails_app_two;
}
# Location block for the assets.
# See: http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
#
# '^~ /assets/' is a 'prefix string', not a regex.
# '^~' will prevent further location searching after this location is matched.
#
# 'root' is inherited from the parent block. With the default Rails directory
# structure it should point to 'app_root/public'.
#
location ^~ /assets/ {
# To serve the pre-gzipped version of the files, if available.
# The non-compressed versions MUST be available too, or a 404 will be returned.
# The general gzip directives in the 'http' block are still applied.
gzip_static on;
# Since Rails automatically appends digest fingerprints to asset file names,
# we don't need to worry about expiring them.
expires max;
add_header Cache-Control public;
# Or:
# expires 12h;
# add_header Cache-Control "public, must-revalidate";
# The 'try_files' directive is NOT inherited from the parent block.
try_files $uri =404;
# We could also use a less strict directive that falls back to the Rails app
# if a requested asset cannot be found. In this case, the cache headers here
# configured will be ignored and Rails will set them automatically.
# try_files $uri @rails_app;
# Normally the Rails app takes care of serving the static file 'public/404.html'
# when a 404 occours. Here, however, it will be handled by nginx.
error_page 404 /404.html;
}
}
}
# A note on $uri and the try_files directive:
#
# try_files /maintenance.html $uri $uri/index.html $uri.html @rails_app;
#
#
# /maintenance.html
# if this file exists (likely a symlink), the app is probably not
# available (updating the DB?). We serve it directly.
#
# $uri
# it could be an asset.
# e.g. assets/application.css
#
# $uri/index.html
# it could be a directory in the file system. In that
# case we look for an index.html file.
#
# $uri.html
# it could be an actual html file.
# e.g. 500.html
#
# @rails_app
# finally, if all other tests fail, we pass the request to the app
#
@rmsy

This comment has been minimized.

Copy link

@rmsy rmsy commented Jan 23, 2019

Very helpful, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.