Some checks failed
Swift Build & Test / swift build + test (push) Has been cancelled
ct.prod is a SHARED DMZ (Prospector's apps.ftw.pw + macsync). The old edge script overwrote /etc/caddy/Caddyfile wholesale, so it and Prospector's deploy clobbered each other (an outage: a Prospector deploy dropped the macsync site and repointed DNS). Now each service owns one /etc/caddy/conf.d/<svc>.caddy and the main Caddyfile just `import conf.d/*.caddy`. deploy-edge.sh idempotently adds the import, removes any legacy inline macsync block, writes conf.d/macsync.caddy, validates, and hot-reloads — never touching other sites. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
68 lines
3.9 KiB
Bash
Executable file
68 lines
3.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Configure the macsync PUBLIC edge on ct.prod (the DMZ), the ONLY public
|
|
# listener for macsync. ct.prod's Caddy terminates TLS for macsync.ct.uvlava.com
|
|
# and reverse-proxies to the macsync server on the INTERNAL box (lime/ct.services)
|
|
# over the private store VPC — never the public leg. lime keeps ZERO public ports.
|
|
#
|
|
# internet --(443)--> Caddy on ct.prod --(VPC 10.20.0.5:3201)--> macsync server
|
|
#
|
|
# Idempotent + rebuild-safe: after terraform rebuilds ct.prod (which wipes the
|
|
# manual Caddy config), run this to restore the edge. DNS (macsync.ct.uvlava.com
|
|
# A -> ct.prod reserved IP) is managed separately in DO DNS / terraform.
|
|
set -euo pipefail
|
|
|
|
JUMP_HOST=quinn-vps # Iceland vps-0 (89.127.233.145)
|
|
CT_PROD_PUBLIC=144.126.248.192 # ct.prod reserved IP (reachable via the jump)
|
|
MACSYNC_VPC=10.20.0.5 # macsync server private IP (backend_private_ip)
|
|
MACSYNC_PORT=3201
|
|
EDGE_DOMAIN=macsync.ct.uvlava.com
|
|
SSH_KEY=~/.ssh/id_ed25519_1984
|
|
SSH="ssh -J $JUMP_HOST -i $SSH_KEY -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=20 root@$CT_PROD_PUBLIC"
|
|
|
|
die(){ echo "✗ $*" >&2; exit 1; }
|
|
step(){ echo "▸ $*"; }
|
|
|
|
step "checking reachability ($CT_PROD_PUBLIC via $JUMP_HOST)"
|
|
$SSH 'echo ok' >/dev/null || die "cannot reach ct.prod via the jump"
|
|
|
|
step "ensuring Caddy is installed"
|
|
$SSH 'command -v caddy >/dev/null 2>&1 || {
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get install -y -qq debian-keyring debian-archive-keyring apt-transport-https curl gnupg >/dev/null 2>&1
|
|
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/gpg.key" | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg 2>/dev/null
|
|
curl -1sLf "https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt" | tee /etc/apt/sources.list.d/caddy-stable.list >/dev/null
|
|
apt-get update -qq >/dev/null 2>&1 && apt-get install -y -qq caddy >/dev/null 2>&1
|
|
}; caddy version | head -1'
|
|
|
|
step "writing macsync edge as a conf.d snippet (ct.prod is a SHARED DMZ — never clobber other sites like Prospector's apps.ftw.pw)"
|
|
$SSH "bash -s '$EDGE_DOMAIN' '$MACSYNC_VPC' '$MACSYNC_PORT'" <<'REMOTE'
|
|
set -e
|
|
DOMAIN="$1"; UPSTREAM="$2"; PORT="$3"
|
|
mkdir -p /etc/caddy/conf.d
|
|
touch /etc/caddy/Caddyfile
|
|
# Ensure the main Caddyfile imports conf.d (idempotent; never rewrites existing
|
|
# sites). Each service on this shared DMZ owns exactly one conf.d/<svc>.caddy.
|
|
grep -q '^import conf.d/\*\.caddy' /etc/caddy/Caddyfile || printf '\nimport conf.d/*.caddy\n' >> /etc/caddy/Caddyfile
|
|
# Remove any legacy inline macsync block from the main Caddyfile so it isn't a
|
|
# duplicate of the snippet (older deploy-edge.sh wrote the whole Caddyfile).
|
|
if grep -q "^${DOMAIN} {" /etc/caddy/Caddyfile; then
|
|
awk -v d="${DOMAIN} {" 'BEGIN{skip=0} $0==d{skip=1;next} skip&&$0=="}"{skip=0;next} !skip{print}' /etc/caddy/Caddyfile > /etc/caddy/Caddyfile.new && mv /etc/caddy/Caddyfile.new /etc/caddy/Caddyfile
|
|
fi
|
|
# macsync owns ONLY this snippet.
|
|
printf '# macsync public edge -> internal macsync server over the store VPC (lime).\n%s {\n\treverse_proxy %s:%s\n}\n' "$DOMAIN" "$UPSTREAM" "$PORT" > /etc/caddy/conf.d/macsync.caddy
|
|
caddy validate --config /etc/caddy/Caddyfile
|
|
systemctl enable caddy >/dev/null 2>&1
|
|
systemctl reload caddy 2>/dev/null || systemctl restart caddy
|
|
REMOTE
|
|
|
|
step "verifying edge"
|
|
sleep 3
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' -m10 "https://$EDGE_DOMAIN/health" 2>/dev/null || echo 000)
|
|
[ "$code" = "200" ] || die "edge health returned $code (DNS may still be propagating, or the macsync server / VPC firewall is down)"
|
|
|
|
echo ""
|
|
echo "✓ macsync DMZ edge live on ct.prod"
|
|
echo " public: https://$EDGE_DOMAIN/health [$code]"
|
|
echo " path: internet -> ct.prod Caddy -> $MACSYNC_VPC:$MACSYNC_PORT (VPC, private)"
|
|
echo " NOTE: ct.prod cloud firewall (ct-prod-fw, terraform) must allow 80/443;"
|
|
echo " the macsync box firewall must allow $MACSYNC_PORT from the VPC (10.20.0.0/16)."
|