{ pkgs, config, ... }:
{
  environment.systemPackages = [ pkgs.traefik ];
  environment.persistence.${config.custom.impermanence.persistPath}.files = [ "/acme/acme.json" ];

  services.traefik = {
    enable = true;

    staticConfigOptions = {
      global = {
        checkNewVersion = false;
        sendAnonymousUsage = false;
      };

      accessLog = { };

      api = {
        dashboard = true;
      };

      certificatesResolvers = {
        letsencrypt = {
          acme = {
            email = "petru@paler.net";
            storage = "/acme/acme.json";
            tlsChallenge = { };
          };
        };
      };

      entryPoints = {
        web = {
          address = ":80";
          http = {
            redirections = {
              entrypoint = {
                to = "websecure";
                scheme = "https";
                permanent = true;
              };
            };
          };
        };
        websecure = {
          address = ":443";
          http = {
            tls = {
              certResolver = "letsencrypt";
            };
          };
        };
        tailscale = {
          address = "100.75.147.49:8080";
        };
      };
    };

    dynamicConfigOptions = {
      http = {
        services = {
          # edgy over Tailscale
          alo-cluster.loadBalancer.servers = [ { url = "http://100.64.229.126:10080"; } ];
          varnish-cache.loadBalancer.servers = [ { url = "http://localhost:6081"; } ];
        };

        routers = {
          api = {
            entryPoints = "tailscale";
            rule = "Host(`traefik-cloud.v.paler.net`)";
            service = "api@internal";
          };

          wordpress-paler-net = {
            entryPoints = "websecure";
            rule = "Host(`wordpress.paler.net`)";
            service = "varnish-cache";
          };

          ines-paler-net = {
            entryPoints = "websecure";
            rule = "Host(`ines.paler.net`)";
            service = "varnish-cache";
          };

          coachingfor-me = {
            entryPoints = "websecure";
            rule = "Host(`coachingfor.me`)";
            service = "varnish-cache";
          };

          coachingfor-work = {
            entryPoints = "websecure";
            rule = "Host(`coachingfor.work`)";
            service = "varnish-cache";
          };

          petru-ines-paler-net = {
            entryPoints = "websecure";
            rule = "Host(`petru.ines.paler.net`)";
            service = "varnish-cache";
          };

          liam-paler-net = {
            entryPoints = "websecure";
            rule = "Host(`liam.paler.net`)";
            service = "varnish-cache";
          };

          tomas-paler-net = {
            entryPoints = "websecure";
            rule = "Host(`tomas.paler.net`)";
            service = "varnish-cache";
          };

          musictogethersilvercoast-pt = {
            entryPoints = "websecure";
            rule = "Host(`musictogethersilvercoast.pt`)";
            service = "varnish-cache";
          };

          alo-land = {
            entryPoints = "websecure";
            rule = "Host(`alo.land`)";
            service = "varnish-cache";
          };
        };
      };
    };
  };

  # to make the Souin plugin installable, cf. https://community.traefik.io/t/cant-use-plugins-error-mkdir-plugins-storage-permission-denied/16341/3
  systemd.services.traefik.serviceConfig.WorkingDirectory = "/var/lib/traefik";

  services.varnish = {
    enable = true;
    http_address = "localhost:6081";
    config = ''
      vcl 4.0;

      backend default {
        .host = "100.64.229.126";
        .port = "10080";
      }

      sub vcl_backend_response {
          # default TTL if backend didn't specify one
          if (beresp.ttl <= 0s) {
            set beresp.ttl = 1h;
          }
          # serve stale content in case home link is down
          set beresp.grace = 240h;
      }
    '';
  };
}
