nginx + Rails (puma) on NixOS

Not too much on the web about how to set this up, so here’s an example.

nginx serves static content for example.com and rs.io and passes not-static-content requests made to rs.io to 127.0.0.:3000–which, in this case, is Rails and puma, who then handle rendering it dynamically.

services.nginx = {
  enable = true;
  upstreams.rails.servers."127.0.0.1:3000" = {};
  virtualHosts."example.com" = {
    root = "/var/www/example";
    forceSSL = true;
    enableACME = true;
    extraConfig = ''
		  rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
		  try_files $uri.html $uri/ $uri =404;
		  '';
  };
  virtualHosts."www.rs.io" = {
    root = "/var/www/rs.io";
    extraConfig = '' return 301 https://rs.io$request_uri; '';
  };
  virtualHosts."rs.io" = {
    root = "/var/www/rs.io";
    enableACME = true;
    locations."/".extraConfig = ''
			       << excerpted block >>
			       '';
    extraConfig = ''
		  index index.html;
		  try_files $uri $uri/ =404;
		  '';
  };
};

This block is what goes at the highlighted line (I excerpted it so things would display a little nicer):

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

if (-f $request_filename) {
  break;
}

if (-f $request_filename/index.html) {
  rewrite (.*) $1/index.html break;
}

if (-f $request_filename.html) {
  rewrite (.*) $1.html break;
}

if (!-f $request_filename) {
  proxy_pass http://rails;
  break;
}

There is more detail on how this bit works here, where I adopted it from.

You've read this far⁠—want more?

Subscribe and I'll e-mail you updates along with the ideas that I don't share anywhere else.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.