{ config, lib, ... }: let proxyNet = config.homelab.apps.traefik.sharedNetworkName; in { options.homelab.traefikRouters = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { rule = lib.mkOption { type = lib.types.str; description = "The Traefik router rule, e.g. Host(`example.com`)"; }; port = lib.mkOption { type = lib.types.int; description = "The port the service listens on"; }; middlewares = lib.mkOption { type = lib.types.listOf lib.types.str; default = []; description = "Middlewares to apply"; }; tls = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to enable TLS"; }; entryPoints = lib.mkOption { type = lib.types.listOf lib.types.str; default = []; description = "Entrypoints to use"; }; extraLabels = lib.mkOption { type = lib.types.attrsOf lib.types.str; default = {}; description = "Extra labels to apply"; }; }; }); default = {}; description = "Declarative Traefik router configuration"; }; config = { # Generate labels for containers based on homelab.traefikRouters # This assumes that the name in homelab.traefikRouters matches the container name. virtualisation.oci-containers.containers = lib.mapAttrs (name: router: { labels = { "traefik.enable" = "true"; "traefik.docker.network" = proxyNet; "traefik.http.routers.${name}.rule" = router.rule; "traefik.http.services.${name}.loadbalancer.server.port" = toString router.port; } // lib.optionalAttrs (router.middlewares != []) { "traefik.http.routers.${name}.middlewares" = builtins.concatStringsSep "," router.middlewares; } // lib.optionalAttrs router.tls { "traefik.http.routers.${name}.tls" = "true"; } // lib.optionalAttrs (router.entryPoints != []) { "traefik.http.routers.${name}.entryPoints" = builtins.concatStringsSep "," router.entryPoints; } // router.extraLabels; }) config.homelab.traefikRouters; }; }