Webgateway (NGINX, HAProxy)

This role provides a stack of components that enables you to serve a web application via HTTP. In addition, you can do load balancing and configure failover support.


  • HAProxy: 2.3.14

  • Nginx: 1.20.2

Role architecture

The webgateway role uses:

  • the nginx web server

  • the HAProxy load balancer and proxy server

We provide basic config for both services. You will have to add custom configuration to serve your site.

Both services support config reload and changing the binary without downtime.


Although we install nginx and HAProxy, there is no need to use them both. Since there is no connection between them w.r.t configuration, you can still use only one of them and leave the other one as is.

How we differ from what you are used to

Here is how we differ from what you already know from common Linux distributions and how you are used to configure, start, stop and maintain these packages.

  • configuration file locations:

    We do not edit files in /etc/nginx/* or /etc/haproxy/*, respectively. Since we use NixOS, files have to be edited in /etc/local, followed by a NixOS rebuild which copies them into the Nix store and activates the new configuration. To do so, run the command sudo fc-manage -b

  • service control:

    We use systemd to control processes. You can use familiar commands like sudo systemctl restart nginx to control services. However, remember that invoking sudo fc-manage -b is necessary to put configuration changes into effect. A simple restart is not sufficient. For further information, see Local Configuration.


Put your HAProxy configuration in /etc/local/haproxy/haproxy.cfg. You can find an example config at /etc/local/haproxy/haproxy.cfg.example. Please refer to the official documentation for more details.

If you need more than just one centralized configuration file, you can use multiple files named *.cfg in the local configuration directory. They will get merged along in alphabetical order.

Changes to your custom config will cause haproxy to reload without downtime on the next fc-manage run.

The final haproxy config file can be shown with: haproxy-show-config.


We provide basic config. You have to configure at least one virtual host.

Changes to your custom config will cause nginx to reload without downtime on the next fc-manage run if the config is valid. It will display a warning if invalid settings are found in the nginx config.

Note that changes to listen directives that are incompatible with the running config may require a manual Nginx restart that drops connections. Using reuseport can avoid such situations (see below).

After building it with sudo fc-manage -b, the final nginx config file can be shown with: nginx-show-config

You can check if the config is valid with: nginx-check-config. The script also warns about potential security issues with your current config.

The recommended method is structured configuration via Nix code as described in the next section. We still support plain nginx config and structured JSON config in /etc/local/nginx.

Plain Configuration (old)

If you want to use plain Nginx configuration add the config file as /etc/local/nginx/nginx.conf. It has to contain at least one server block declaration as described in the official documentation. Your files will then be integrated with our nginx base config. Therefore, please omit the http clause. It is already set by the base config.

See /etc/local/nginx/example-configuration for an example and /etc/local/nginx/README.txt.

JSON Configuration (old)

Although not recommended anymore, JSON config can be added to /etc/local/nginx, alongside with plain nginx config files. Nix config should be used instead, as described above. JSON config supports the same options as Nix config so converting from JSON to Nix is basically just a syntax change.

See /etc/local/nginx/README.txt for an example and more info.


nginx’ access logs are stored by default in /var/log/nginx/access.log. Individual log files for virtual hosts can be defined in the corresponding configuration sections. We use the anonymized log format for GDPR conformance by default.

Add this to an extraConfig block in Nix config or your plain nginx config:

access_log /var/log/nginx/app.log;

nginx’ error logs go to systemd’s journal by default. To view them, use journalctl(1) as usual, e.g.:

$ journalctl --since -1h -u nginx