{ config, pkgs, lib, ... }: with lib; let cfg = config.my.networking.caddy; in { options.my.networking.caddy = { enable = lib.mkEnableOption "Enable caddy as reverse proxy"; }; config = lib.mkIf cfg.enable { age.secrets = { cloudflare-tegola-apiKey = { file = ../../secrets/cloudflare-tegola-apiKey.age; owner = config.services.caddy.user; group = config.services.caddy.group; }; }; services.caddy = { enable = true; package = pkgs.caddy-custom; # acmeCA = "https://acme-staging-v02.api.letsencrypt.org/directory"; # ONLY FOR DEVELOPMENT! globalConfig = '' admin :2024 servers { metrics } ''; extraConfig = '' (cloudflare) { tls { dns cloudflare {env.CLOUDFLARE_KEY} resolvers 1.1.1.1 100.100.100.100 } } ''; }; systemd.services.caddy.serviceConfig = { EnvironmentFile = config.age.secrets.cloudflare-tegola-apiKey.path; AmbientCapabilities = "CAP_NET_BIND_SERVICE"; }; # By default, the module create a custom user but it lacks permission to read caddy files systemd.services.promtail.serviceConfig = { Group = lib.mkForce config.services.caddy.group; User = lib.mkForce config.services.caddy.user; }; services.promtail = { enable = true; configuration = { server.http_listen_port = 9080; server.grpc_listen_port = 0; clients = [ { url = "http://metrics.internal:3100/loki/api/v1/push"; } ]; scrape_configs = [ { job_name = "journal"; journal = { max_age = "12h"; labels = { job = "systemd-journal"; }; }; relabel_configs = [ { source_labels = [ "__journal__systemd_unit" ]; regex = "(.*)\\.service"; target_label = "service"; } { source_labels = [ "__journal__hostname" ]; target_label = "hostname"; } ]; } { job_name = "caddy"; static_configs = [ { targets = [ "localhost" ]; labels = { job = "caddylogs"; __path__ = "${config.services.caddy.logDir}/*.log"; }; } ]; } ]; }; }; networking.firewall.allowedTCPPorts = [ 80 443 2024 ]; networking.firewall.allowedUDPPorts = [ 80 443 ]; }; }