Files
cc-ci/modules/proxy.nix
autonomic-bot a385148af9 M2: Drone server + exec runner up; infra as idempotent-reconcile oneshots
Convert proxy+drone bring-up to writeShellApplication systemd oneshots that
reconcile every activation (orchestrator steer). pkgs.abra overlay. Runner
connected via RPC (polling, capacity=2). install.md = clone + nixos-rebuild switch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 22:59:59 +01:00

64 lines
2.8 KiB
Nix

# Reverse proxy = the canonical Co-op Cloud `traefik` recipe, deployed via abra in
# wildcard / file-provider mode (operator's pre-issued 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".
#
# Declared as an idempotent-RECONCILE systemd oneshot (like swarm-init): it inspects current
# state and converges every activation/boot, self-healing drift (redeploys if the stack is gone,
# re-inserts secrets if missing). No run-once sentinel. So a from-scratch install is just
# `nixos-rebuild switch` + operator preconditions (D8) — no manual post-steps.
{ pkgs, ... }:
let
reconcile = pkgs.writeShellApplication {
name = "cc-ci-reconcile-proxy";
runtimeInputs = with pkgs; [ abra docker jq gnused gnugrep coreutils git ];
text = ''
PROXY_DOMAIN="traefik.ci.commoninternet.net"
CERT_DIR="/var/lib/ci-certs/live"
ENV_FILE="$HOME/.abra/servers/default/$PROXY_DOMAIN.env"
# Fail visibly (failed unit) if the operator cert is missing do NOT silently skip.
if [ ! -r "$CERT_DIR/fullchain.pem" ] || [ ! -r "$CERT_DIR/privkey.pem" ]; then
echo "FATAL: wildcard cert missing at $CERT_DIR (operator precondition)" >&2
exit 1
fi
abra server ls -m -n >/dev/null 2>&1 || abra server add --local -n || true
abra recipe fetch traefik -n >/dev/null
[ -f "$ENV_FILE" ] || abra app new traefik -s default -D "$PROXY_DOMAIN" -n
set_env() {
sed -i -E "/^[[:space:]]*#?[[:space:]]*$1=/d" "$ENV_FILE"
printf '%s=%s\n' "$1" "$2" >> "$ENV_FILE"
}
set_env LETS_ENCRYPT_ENV ""
set_env WILDCARDS_ENABLED "1"
set_env SECRET_WILDCARD_CERT_VERSION "v1"
set_env SECRET_WILDCARD_KEY_VERSION "v1"
set_env COMPOSE_FILE '"compose.yml:compose.wildcard.yml"'
have_secret() { docker secret ls --format '{{.Name}}' | grep -q "_$1_v1$"; }
have_secret ssl_cert || abra app secret insert "$PROXY_DOMAIN" ssl_cert v1 "$CERT_DIR/fullchain.pem" -f -n
have_secret ssl_key || abra app secret insert "$PROXY_DOMAIN" ssl_key v1 "$CERT_DIR/privkey.pem" -f -n
# Converge the stack (idempotent: no-op if already at desired state).
abra app deploy "$PROXY_DOMAIN" -n -C
'';
};
in
{
systemd.services.deploy-proxy = {
description = "Reconcile the Co-op Cloud traefik proxy (wildcard/no-ACME) 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;
ExecStart = "${reconcile}/bin/cc-ci-reconcile-proxy";
};
};
}