Skip to content

Instantly share code, notes, and snippets.

@brodock
Last active August 29, 2015 14:04
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save brodock/dca87fe888c02abcaf01 to your computer and use it in GitHub Desktop.
Save brodock/dca87fe888c02abcaf01 to your computer and use it in GitHub Desktop.
Silver Bullet Nginx Vhost Recipe for Rails application with HTTPS + Webp + Capistrano + Linux FHS
# This file should be placed at /etc/logrotate.d/
/srv/*/shared/log/*.log {
daily
missingok
dateext
rotate 30 # amount of days to keep compressed logs (you should backup it up externally)
compress
delaycompress
notifempty
copytruncate
}
# READ THIS CAREFULLY:
#
# This template will include some "pseudo-variables" that you have to change manually to the desired values
# Use as an inspiration to create templates to a automation tools like Chef/Puppet/Ansible/Capistrano
# To make it distinc from nginx variables, the "pseudo-variables" when used, will follow the format: {$variable_name}
# This is the suggested default values for the "pseudo-variables", and their description:
# Your application host will be used as a convention for directories and other stuffs
$application_host = "example.com";
# Rails application server timeout (we have to match the value here in order to not display Gateway Timeout error)
$application_timeout = 300;
## Template Start Here ##
upstream application {
## Uncomment if you have set up puma/unicorn to listen on a unix socket (recommended).
# server unix:/srv/{$application_host}/shared/tmp/sockets/application.socket;
## Uncomment if puma/unicorn are configured to listen on a tcp port.
## Check the port number in your puma/unicorn config file
# server 127.0.0.1:9292;
}
server {
listen 80;
server_name {$application_host};
rewrite ^/(.*) https://$server_name permanent;
}
server {
listen 443 ssl spdy;
server_name {$application_host};
server_tokens off; # Don't show the nginx version number
root /srv/{$application_host}t/current/public;
# The maxium amount of information any HTTP request can send to the server
# This also determines the maximum size of upload file requests
client_max_body_size 100m;
# Enable SSL and point to the correct certificate key and certificate chain file
# To know how to generate a server chain, please read:
ssl on;
ssl_certificate /srv/{$application_host}/shared/ssl/server-chain.pem;
ssl_certificate_key /srv/{$application_host}/shared/ssl/server.key;
# Do not enable SSLv3 or any lower version, it's UNSAFE (fuck you, IE6) - Poodle Attack (CVE-2014-3566)
# Advice: If you need to enforce the highest security possible, disable TLSv1.
# While IE8+ starting with Windows 7, supports TLSv1.1 and TLSv1.2, it's not enabled by default
# which means, no IE user, even thous using IE11 will not, by default, be able to use your application.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Advice: DO NOT USE RC4, if you are thinking otherwhise please read:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers on;
# SSL Session Cache:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Enable HSTS, to let the browser know that we only accept HTTPS requests (prevents MITM attack)
# Warning: you will not be able to send HTTP traffic anymore in the future, so read before use:
# http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
add_header Strict-Transport-Security max-age=31536000;
# Prevent any website to embed yours using iframe
add_header X-Frame-Options SAMEORIGIN;
# Prevent MIME spoofing: http://stackoverflow.com/questions/18337630/what-is-x-content-type-options-nosniff
add_header X-Content-Type-Options nosniff;
# individual nginx logs for this vhost
access_log /var/log/nginx/{$application_host}_access.log;
error_log /var/log/nginx/{$application_host}_error.log;
location / {
# serve static files from defined root folder;
# @application is a named location for the upstream fallback, see below
try_files $uri $uri/index.html $uri.html @application;
}
# if a file, which is not found in the root folder is requested,
# then the proxy pass the request to the upsteam (rails application server)
location @application {
proxy_read_timeout {$application_timeout};
proxy_connect_timeout {$application_timeout};
proxy_redirect off;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://application;
}
location ~ ^/(assets)/ {
root /srv/{$application_host}/current/public;
#
# Webp support via Content Negotiation
# https://www.igvita.com/2013/05/01/deploying-webp-via-accept-content-negotiation/
#
# check Accept header for webp, check if .webp is on disk
if ($http_accept ~* "webp") { set $webp_accept "true"; }
if (-f $request_filename.webp) { set $webp_local "true"; }
# if WebP variant is available, serve Vary
if ($webp_local = "true") {
add_header Vary Accept;
}
# drop Vary for IE users, mark resource as private
if ($http_user_agent ~* "(?i)(MSIE)") {
proxy_hide_header Vary;
add_header Cache-Control private;
}
# if WebP is supported by client, serve it
if ($webp_accept = "true") {
rewrite (.*) $1.webp break;
}
#
# Gzip static assets and expiration control
#
# Enable gzip compression as per rails guide:
# http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
gzip_static on;
expires max;
add_header Cache-Control public;
}
error_page 502 /502.html;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment