Using Traefik on NixOS - MSF-OCB/NixOS Wiki
Enabling the Traefik service
We have a standard configuration for Traefik which can easily be activated by setting
settings.services.traefik.enable = true;
in the server's configuration file.
Having traffic forwarded to a container
Note: if you need certificates to be obtained via a DNS challenge (for websites that are not publicly reachable), please check the following section as well.
When Traefik is enabled, a container can be exposed through Traefik by setting the following labels in the docker-compose.yml
file and registering the container on the web
network:
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.ocb.msf.org`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
networks:
- web
- default
Careful: only the front-end should be connected to the web
network, all other containers will communicate through the default
network.
The web
network is an external network, defined by the Traefik service.
You make it known to your docker-compose project by including the following top-level section:
networks:
web:
external: true
The labels mentioned above, will expose the service running in the container over HTTPS on port 443 on the specified domain with a certificate generated by Let's Encrypt.
HTTP port 80 is automatically forwarded to HTTPS and HSTS headers are enabled. Additionally, gzip compression is also enabled by default.
Generating certificates using DNS challenges
For internal servers and servers on the field, that are not reachable from the internet, we can use a DNS challenge to generate the certificates.
If your public URL is myapp.ocb.msf.org
, you need to add the following ALIAS
record in our public DNS zone:
_acme-challenge.myapp.ocb.msf.org CNAME _automatic-certificate-validation.ocb.msf.org
For URLs that are re-used in different locations (e.g. applications on the field), this CNAME
will usually already be in place.
Due to limitations on the number of ALIAS
records allowed to point to a single resource set in Azure, we introduced _two._automatic-certificate-validation.ocb.msf.org
, pointing to _automatic-certificate-validation.ocb.msf.org
in order to be able to continue to use ALIAS
records. We might need to introduce additional such records in the future.
It is not needed to add this entry to any internal DNS servers, as it will only be queried by the Let's Encrypt servers that are outside of our network.
Then, you need to make sure that the required DNS credentials are available on the server in question.
To do so, you edit the file secrets/secrets.yml
using Ansible Vault, as explained here,
and you make sure that the dns_credentials
secret is made available to the server in question.
After having edited, committed and pushed this file, the NixOS config of the server should be rebuild by running sudo systemctl start nixos_rebuild_config
.
After having done this, you follow the steps from the previous section to configure Traefik using labels in the docker-compose.yml
file, but you add the following additional label to your docker container to instruct Traefik to use a DNS challenge:
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt_dns"
and certificates will be generated using DNS challenges.
Connecting to the Traefik dashboard
The Traefik dashboard gives a graphical overview of the services that have been configured.
Since it exposes internal information and also exposes an API, it is only accessible on localhost
, but you can use an SSH tunnel to connect to the dashboard on any server.
To connect to the dashboard of a server, you can do the following:
- Make sure you are using Firefox, since Chromium-based browsers do not allow proxying
localhost
- Configure Firefox to use a SOCKS proxy on port 9443 (the FoxyProxy extension is useful to toggle proxies with a single click)
- Connect to the server with
ssh -D 9443 my_server
- Browse to https://localhost:8080/dashboard/