Basic Nginx Config For Rails Apps

October 27, 20213 min read


In the beginning, setting up Nginx and configuring it can be painful. That’s why I decided to share with you what is my typical Nginx configuration for Rails apps.

Note (use at your own risk): Remember that the code snippet that I’ll provide is just an example. Make sure that the config is well tested before using it in production.

Let’s assume that the name of our app is example and our domain is example.com.

Nginx Config

I’ll first start with the http server block.

HTTP Server Block

server {
  server_name example.com www.example.com;
  listen 80;
  listen [::]:80;

  return 301 https://example.com$request_uri;

  access_log off;
  return 404;

Here we make sure to permanently redirect to the https. My personal preference when it comes to how the URL looks like is to omit www. preceding the domain name.

An important thing to do is to disable the access log. This could improve the performance.

Let’s continue with the https server block.

HTTPS Server Block

server {
  server_name example.com www.example.com;

  if ($host = www.example.com) {
    return 301 https://example.com$request_uri;

  access_log  /var/log/nginx/example.access.log;

  location / {
    root /home/example-app/apps/example/current/public;
    passenger_enabled on;
    passenger_min_instances 3;
    rails_env production;

    client_max_body_size 11m;

    location ~* ^/(assets|fonts|favicon.ico) {
      allow all;
      expires 365d;
      gzip_http_version 1.0;
      add_header Cache-Control public;

  listen [::]:443 ssl ipv6only=on; # managed by Certbot
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

Here we make sure that all www requests are permanently redirected to non-www.

The access log here is enabled because we want to know what’s happening with our app.

The location block is pretty standard. I prefer using passenger in production.

client_max_body_size 11m sets the maximum allowed size of the client request body. This simple protection comes handy when you have to support a system where images and other files are uploaded.

The last 6 lines of the https server block are dedicated to the port (443) that we’re listening to and the SSL certificate.

Final notes

Please note that this is a basic configuration. As your app grows, it will likely become more and more complex.

Always make sure to test your nginx configuration before reloading your server by using the following command:

sudo nginx -t

I uploaded the code snippet to GitHub and here’s the repo URL:


Hope you liked this post! :)

© 2021, Radoslav Genchev