Skip to content

traefik

Modern HTTP reverse proxy

Examples

Simple (Cloudflare)

nix
{config, ...}: {
  nps.stacks.traefik = {
    enable = true;

    domain = "example.com";
    # Token will be used to fetch Letsencrypt wildcard certificates automatically (DNS challenge)
    extraEnv = {
      CF_DNS_API_TOKEN.fromFile = config.sops.secrets."traefik/cf_api_token".path;
    };
  };
}

With different DNS provider

nix
{config, ...}: {
  nps.stacks.traefik = {
    enable = true;

    domain = "example.com";
    staticConfig.certificatesResolvers.letsencrypt.acme.dnsChallenge.provider = "porkbun";
    extraEnv = {
      PORKBUN_API_KEY.fromFile = config.sops.secrets."traefik/porkbun_api_key".path;
      PORKBUN_SECRET_API_KEY.fromFile = config.sops.secrets."traefik/porkbun_secret_api_key".path;
    };
  };
}

With Geoblock

nix
{config, ...}: {
  nps.stacks.traefik = {
    enable = true;

    domain = "example.com";
    extraEnv.CF_DNS_API_TOKEN.fromFile = config.sops.secrets."traefik/cf_api_token".path;

    # For exposed services, we can limit access to certain countries using a geoblock middleware
    geoblock.allowedCountries = ["DE"];
  };
}

With file provider

nix
{config, ...}: {
  nps.stacks.traefik = {
    enable = true;

    domain = "example.com";
    extraEnv.CF_DNS_API_TOKEN.fromFile = config.sops.secrets."traefik/cf_api_token".path;
    provider = "file";
  };
}

Stack Options

nps.stacks.traefik.crowdsec.enableLogCollection

Whether logs from Traefik should be collected by CrowdSec. Enabling this will configure the acquis settings for CrowdSec.

Type
plaintext
boolean
Default
nix
config.nps.stacks.crowdsec.enable
Declaration

nps.stacks.traefik.crowdsec.middleware.bouncerKeyFile

Path to the file containing the key for the Traefik bouncer. If the middleware option is enabled, a Bouncer will be automatically provisioned in CrowdSec. Also a new crowdsec middleware will be registered in Traefik and added to the public chain. This will block requests to exposed services that are detected as malicious by Crowdsec.

You can generate a bouncer key using openssl: openssl rand -hex 32

Type
plaintext
absolute path
Declaration

nps.stacks.traefik.crowdsec.middleware.enable

Whether to setup a Traefik middleware. Make sure to also configure the bouncerKeyFile option.

Type
plaintext
boolean
Default
nix
config.nps.stacks.crowdsec.enable
Declaration

nps.stacks.traefik.domain

Base domain handled by Traefik

Type
plaintext
string
Declaration

nps.stacks.traefik.dynamicConfig

Dynamic configuration for Traefik. By default, the module will setup two middlewares: private & public. The private middleware (applied by default to all services) will only allow access from internal networks. The public middleware will allow access from the internet. It will be configured with a rate limit, security headers and a geoblock plugin (if enabled). If enabled, Crowdsec will also be added to the public middleware chain.

Type
plaintext
YAML 1.1 value
Default
nix
{ }
Declaration

nps.stacks.traefik.enable

Wheter to enable Traefik. The Traefik stack ships preconfigured with a dynamic and static configuration.

Type
plaintext
boolean
Default
nix
false
Example
nix
true
Declaration

nps.stacks.traefik.enableGrafanaAccessLogDashboard

Whether to enable Grafana Access Log Dashboard.

Type
plaintext
boolean
Default
nix
false
Example
nix
true
Declaration

nps.stacks.traefik.enableGrafanaMetricsDashboard

Whether to enable Grafana Metrics Dashboard.

Type
plaintext
boolean
Default
nix
false
Example
nix
true
Declaration

nps.stacks.traefik.enablePrometheusExport

Whether to enable Prometheus Export.

Type
plaintext
boolean
Default
nix
false
Example
nix
true
Declaration

nps.stacks.traefik.extraEnv

Extra environment variables to set for the container. Variables can be either set directly or sourced from a file (e.g. for secrets).

Type
plaintext
attribute set of (null or boolean or signed integer or string or absolute path or (submodule))
Default
nix
{ }
Example
nix
{
  CF_DNS_API_TOKEN = {
    fromFile = "/run/secrets/secret_name";
  };
  TRAEFIK_LOG_LEVEL = "ERROR";
}
Declaration

nps.stacks.traefik.geoblock.allowedCountries

List of allowed country codes (ISO 3166-1 alpha-2 format) See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements

Type
plaintext
list of string
Default
nix
[ ]
Declaration

nps.stacks.traefik.geoblock.enable

Enable the geoblock plugin for Traefik. This will block access to the services based on the country code of the request. The plugin uses the IP2Location database to determine the country code. If enabled, the geoblock will be used in the public middleware, allowing only requests from the allowed countries.

Type
plaintext
boolean
Default
nix
true
Declaration

nps.stacks.traefik.network.name

Network name for Podman bridge network. Will be used by the Traefik Docker provider

Type
plaintext
string
Default
nix
"traefik-proxy"
Declaration

nps.stacks.traefik.provider

How services are registered in Traefik. "docker" (default): routes are created via container labels (Docker provider). "file": routes and services are generated into the dynamic config file. This is required for on-demand setups (e.g. Sablier), where stopped containers are removed by Quadlet and their labels can therefore not be read anymore.

Type
plaintext
one of "docker", "file"
Default
nix
"docker"
Declaration

nps.stacks.traefik.staticConfig

Static configuration for Traefik. By default, for the configured domain, a wildcard certificate will be requested from Let's Encrypt and used for all services that are registered with Traefik. By default Cloudflare with DNS challenge will be used to request the certificate. This requires the 'CF_DNS_API_TOKEN' environment variable to be present, e.g. by providing it via the extraEnv option.

The DNS provider as well as any other settings can be overwritten. For an example see https://tarow.github.io/nix-podman-stacks/docs/examples.html#change-dns-provider

Type
plaintext
YAML 1.1 value
Default
nix
null
Declaration

nps.stacks.traefik.useSocketProxy

Whether to access the Podman socket through the read-only proxy for the traefik stack. Will be enabled by default if the 'docker-socket-proxy' stack is enabled.

Type
plaintext
boolean
Default
nix
config.nps.stacks.docker-socket-proxy.enable
Declaration

Container Extension

Traefik adds several container options to the existing services.podman.containers.<name> options:

  • port: The main port that Traefik will forward traffic to.
  • expose: Whether the service should be publicly reachable. When false (default), the private middleware is applied, which only allows requests from private CIDR ranges. When true, the public middleware is applied, which allows access from the internet (with rate limit, security headers and optional geoblock/Crowdsec).
  • traefik: Controls how the service is registered in Traefik (name, subDomain, middleware). The service is only registered when traefik.name is set.

Example:

nix
{config, ...}: {
  nps.stacks.streaming.containers.jellyfin = {
    expose = true;

    traefik = {
      subDomain = "movies";
    };
  };
}

services.podman.containers.<name>.expose

Whether the service should be exposed (e.g. reachable from external IP addresses). When set to false, the private middleware will be applied by Traefik. The private middleware will only allow requests from private CIDR ranges.

When set to true, the public middleware will be applied. The public middleware will allow access from the internet. It will be configured with a rate limit, security headers and a geoblock plugin (if enabled). If enabled, Crowdsec will also be added to the public middleware chain.

Type
plaintext
boolean
Default
nix
false
Declaration

services.podman.containers.<name>.port

Main port that Traefik will forward traffic to. If Traefik is disabled, it will instead be added to the "ports" section

Type
plaintext
null or string or signed integer
Default
nix
null
Declaration

services.podman.containers.<name>.socketActivation.*.port

Port that the socket should listen on

Type
plaintext
string or 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Declaration

services.podman.containers.<name>.traefik.middleware

A mapping of middleware name to a boolean that indicated if the middleware should be applied to the service.

Type
plaintext
attribute set of (submodule)
Default
nix
{ }
Declaration

services.podman.containers.<name>.traefik.middleware.<name>.enable

Whether the middleware should be applied to the service

Type
plaintext
boolean
Default
nix
false
Declaration

services.podman.containers.<name>.traefik.middleware.<name>.order

Order of the middleware. Middlewares will be called in order by Traefik. Lower number means higher priority.

Type
plaintext
signed integer
Default
nix
1000
Declaration

services.podman.containers.<name>.traefik.name

The name of the service as it will be registered in Traefik. Will be used as a default for the subdomain.

If not set (null), the service will not be registered in Traefik.

Type
plaintext
null or string
Default
nix
null
Declaration

services.podman.containers.<name>.traefik.serviceAddressInternal

The internal main address of the service. Can be used for internal communication without going through Traefik, when inside the same Podman network.

If the container shares another container's network namespace (e.g. via network = ["container:gluetun"]), the address of that container is used instead

Type
plaintext
string
Default
nix
"${containerName}:${containerCfg.port}"
Declaration

services.podman.containers.<name>.traefik.serviceHost

The host name of the service as it will be registered in Traefik.

Type
plaintext
string
Default
nix
"${traefikCfg.subDomain}.${nps.stacks.traefik.domain}"
Declaration

services.podman.containers.<name>.traefik.serviceUrl

The full URL of the service as it will be registered in Traefik. This will be the serviceHost including the "https://" prefix.

Type
plaintext
string
Default
nix
"https://${traefikCfg.serviceHost}"
Declaration

services.podman.containers.<name>.traefik.subDomain

The subdomain of the service as it will be registered in Traefik.

Type
plaintext
string
Default
nix
"traefikCfg.name"
Declaration

Container Aliases

nps.stacks.traefik.containers.traefik

Alias of {option}services.podman.containers.traefik.

Type
plaintext
submodule
Declaration