# Recipe Report static site (report.ci.commoninternet.net): a public nginx serving the weekly # "Recipe Report" HTML pages written to /var/lib/cc-ci-reports by the /recipe-report skill. No app, # no secrets — just static files behind traefik + the wildcard TLS (same pattern as dashboard.nix, # but a plain nginx:alpine since there's nothing to render server-side). Content is updated by writing # files into /var/lib/cc-ci-reports; nginx serves them live (no redeploy needed). { pkgs, ... }: let reportsDir = "/var/lib/cc-ci-reports"; stack = pkgs.writeText "cc-ci-reports-stack.yml" '' version: "3.8" services: app: image: nginx:alpine volumes: - type: bind source: ${reportsDir} target: /usr/share/nginx/html read_only: true networks: - proxy deploy: replicas: 1 restart_policy: condition: any labels: - "traefik.enable=true" - "traefik.http.services.ccci-reports.loadbalancer.server.port=80" - "traefik.http.routers.ccci-reports.rule=Host(`report.ci.commoninternet.net`)" - "traefik.http.routers.ccci-reports.entrypoints=web-secure" - "traefik.http.routers.ccci-reports.tls=true" networks: proxy: external: true ''; reconcile = pkgs.writeShellApplication { name = "cc-ci-reconcile-reports"; runtimeInputs = with pkgs; [ docker coreutils ]; text = '' mkdir -p ${reportsDir} # Seed a placeholder index so the site serves something before the first report is generated. if [ ! -f ${reportsDir}/index.html ]; then cat > ${reportsDir}/index.html <<'HTML'
No reports yet — the first one is generated after the weekly recipe-upgrade run.
HTML fi docker stack deploy --detach=true -c ${stack} ccci-reports ''; }; in { systemd.services.deploy-reports = { description = "Reconcile the cc-ci Recipe Report static site (report.ci.commoninternet.net)"; # Ordering-only: chain after the dashboard (proxy→…→dashboard→reports) to avoid concurrent # docker-init races on a fresh host. after = [ "deploy-dashboard.service" "deploy-proxy.service" "swarm-init.service" "docker.service" "network-online.target" ]; requires = [ "swarm-init.service" "docker.service" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${reconcile}/bin/cc-ci-reconcile-reports"; }; }; }