Nginx

From NixOS Wiki
Revision as of 18:53, 30 March 2018 by imported>Samueldr (Adds a troubleshooting note for ACME certs and nginx.)

Nginx is a lightweight webserver. Configuration is handled using the services.nginx options.

Let's Encrypt certificates

The nginx module for NixOS has native support for Let's encrypt certificates. The manual, chapter 20 explains it in details.

Troubleshooting

Rate limiting

The ACME server for Let's encrypt has rate limits. There is a known issue[1] with how NixOS handles automatic certificate generation wherein it is trivial to hit the limits when enabling multiple domains or sub-domains at once.

When hitting the limit, the logs will show as follows:

Mar 30 14:07:38 HOSTNAME systemd[1]: Failed to start Renew ACME Certificate for example.com.
...
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: 2018-03-30 18:08:10,566:DEBUG:acme.client:540: JWS payload:
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: {
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]:   "resource": "new-reg"
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: }
...
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: Connection: close
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: {
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]:   "type": "urn:acme:error:rateLimited",
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]:   "detail": "Error creating new registration :: too many registrations for this IP: see https://letsencrypt.org/docs/rate-limits/",
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]:   "status": 429
Mar 30 14:08:10 HOSTNAME acme-example.com-start[25915]: }

See  #38144 for the current status.

Sample setups

Static blog with ssl enforced in configuration.nix

services.nginx = {
  enable = true;
  virtualHosts."blog.example.com" = {
    enableACME = true;
    forceSSL = true;
    root = "/var/www/blog";
  };
};
# Optional: You can configure the email address used with Let's Encrypt.
# This way you get renewal reminders (automated by NixOS) as well as expiration emails.
security.acme.certs = {
  "blog.example.com".email = "youremail@address.com";
};

LEMP stack (Nginx/MySQL/PHP) in configuration.nix

services.nginx = {
  enable = true;
  virtualHosts."blog.example.com" = {
    enableACME = true;
    forceSSL = true;
    root = "/var/www/blog";
    locations."~ \.php$".extraConfig = ''
      fastcgi_pass 127.0.0.1:9000;
      fastcgi_index index.php;
    '';
  };
};
services.mysql = {
  enable = true;
  package = pkgs.mariadb;
};
services.phpfpm.poolConfigs.mypool = ''
  listen = 127.0.0.1:9000
  user = nobody
  pm = dynamic
  pm.max_children = 5
  pm.start_servers = 2 
  pm.min_spare_servers = 1 
  pm.max_spare_servers = 3
  pm.max_requests = 500
'';