# Reverse proxy = the canonical Co-op Cloud `traefik` recipe, deployed via abra in # wildcard / file-provider mode (wildcard cert as ssl_cert/ssl_key swarm secrets, # LETS_ENCRYPT_ENV empty => NO ACME, no DNS token). See DECISIONS.md "Proxy: real coop-cloud/traefik". # Phase-1c: the cert at CERT_DIR is sops-decrypted from git (cc-ci-secrets) at activation # (modules/secrets.nix wildcard_cert/wildcard_key), NOT an out-of-band operator file drop. # # Phase-2w / WC1.1: traefik is now UNPINNED + health-gated like keycloak — the deploy is driven by # the shared `runner/warm_reconcile.py traefik` (STATELESS = version-rollback-only, NO snapshot): # record last-good version → deploy latest tag → health-gate (a ROUTED host, the dashboard # ci.commoninternet.net, returns 200) → healthy commits last-good / unhealthy rolls back to last-good # + alert. traefik's wildcard-cert/file-provider config (ssl_cert/ssl_key secrets, WILDCARDS_ENABLED, # COMPOSE_FILE) is preserved EXACTLY by the spec's `setup` (warm_reconcile._traefik_setup). The # runner/ tree is copied into the nix store → D8-clean; recipe fetched at runtime → closure stable. # # Idempotent-RECONCILE systemd oneshot (unchanged unit name `deploy-proxy` — other modules order # after it): converges every activation/boot, self-healing drift. No run-once sentinel. { pkgs, ... }: let runnerSrc = ../../runner; reconcile = pkgs.writeShellApplication { name = "cc-ci-reconcile-proxy"; runtimeInputs = with pkgs; [ abra docker git curl jq gnused gnugrep gnutar coreutils ]; text = '' export HOME=/root exec ${pkgs.python3}/bin/python3 ${runnerSrc}/warm_reconcile.py traefik ''; }; in { systemd.services.deploy-proxy = { description = "Reconcile the Co-op Cloud traefik proxy (wildcard/no-ACME, health-gated) via abra"; after = [ "swarm-init.service" "docker.service" "network-online.target" ]; requires = [ "swarm-init.service" "docker.service" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; environment.HOME = "/root"; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; # Generous: a traefik (re)deploy + health-gate; rollback on an unhealthy upgrade. TimeoutStartSec = "900"; ExecStart = "${reconcile}/bin/cc-ci-reconcile-proxy"; }; }; }