M1: proxy via real coop-cloud/traefik (abra, wildcard/no-ACME); recipe deploy+teardown; M1 CLAIMED
Orchestrator decision: deploy canonical coop-cloud traefik via abra instead of a hand-rolled module. abra packaged in Nix (pinned). custom-html deployed over HTTPS (200) via the gateway and torn down clean. docs/install.md seeded. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
60
scripts/deploy-proxy.sh
Executable file
60
scripts/deploy-proxy.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
# Reproducibly deploy the canonical Co-op Cloud `traefik` recipe as cc-ci's reverse proxy,
|
||||
# in wildcard / file-provider mode — serving the operator's pre-issued wildcard cert, with
|
||||
# NO ACME and NO DNS token on the box (see DECISIONS.md "Proxy: real coop-cloud/traefik").
|
||||
#
|
||||
# Idempotent: safe to re-run. Run as root on cc-ci (abra drives the local Docker swarm).
|
||||
# ssh cc-ci 'bash /root/cc-ci/scripts/deploy-proxy.sh'
|
||||
#
|
||||
# Prereqs (declared in the flake): docker + single-node swarm + `proxy` overlay (modules/swarm.nix),
|
||||
# abra (modules/abra.nix), and the wildcard cert at /var/lib/ci-certs/live/ (operator-provided).
|
||||
set -euo pipefail
|
||||
|
||||
PROXY_DOMAIN="${PROXY_DOMAIN:-traefik.ci.commoninternet.net}"
|
||||
CERT_DIR="${CERT_DIR:-/var/lib/ci-certs/live}"
|
||||
ENV_FILE="$HOME/.abra/servers/default/${PROXY_DOMAIN}.env"
|
||||
|
||||
export PATH=/run/current-system/sw/bin:"$PATH"
|
||||
|
||||
echo "==> ensure local abra server"
|
||||
abra server ls -m -n >/dev/null 2>&1 || abra server add --local -n || true
|
||||
|
||||
echo "==> fetch traefik recipe"
|
||||
abra recipe fetch traefik -n >/dev/null
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "==> create traefik app ($PROXY_DOMAIN)"
|
||||
abra app new traefik -s default -D "$PROXY_DOMAIN" -n
|
||||
fi
|
||||
|
||||
echo "==> configure wildcard / no-ACME env"
|
||||
# Set each var deterministically: drop any existing (commented or not) line, then append.
|
||||
# Empty LETS_ENCRYPT_ENV => the traefik router uses no cert resolver => no ACME ever fires.
|
||||
set_env() {
|
||||
local key="$1" val="$2"
|
||||
sed -i -E "/^[[:space:]]*#?[[:space:]]*${key}=/d" "$ENV_FILE"
|
||||
printf '%s=%s\n' "$key" "$val" >> "$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"'
|
||||
echo " env written: $ENV_FILE"
|
||||
|
||||
echo "==> insert wildcard cert secrets (v1) from $CERT_DIR (idempotent)"
|
||||
# Check the actual swarm secret (generated name ${STACK_NAME}_<name>_v1), not abra's
|
||||
# recipe-defined list (which always shows the names with "created on server":"false").
|
||||
have_secret() { docker secret ls --format '{{.Name}}' | grep -q "_${1}_v1\$"; }
|
||||
# Insert from file (-f) so the multi-line PEM is read verbatim, not arg-parsed.
|
||||
if ! have_secret ssl_cert; then
|
||||
abra app secret insert "$PROXY_DOMAIN" ssl_cert v1 "$CERT_DIR/fullchain.pem" -f -n
|
||||
fi
|
||||
if ! have_secret ssl_key; then
|
||||
abra app secret insert "$PROXY_DOMAIN" ssl_key v1 "$CERT_DIR/privkey.pem" -f -n
|
||||
fi
|
||||
|
||||
echo "==> deploy traefik"
|
||||
abra app deploy "$PROXY_DOMAIN" -n -C
|
||||
|
||||
echo "==> done"
|
||||
Reference in New Issue
Block a user