← back to Gallery Agentabrams
deploy/deploy.sh
54 lines
#!/bin/bash
# gallery.agentabrams.com — idempotent deploy (DNS + rsync + nginx + SSL).
# STEVE-GATED: touches Cloudflare DNS + a public Kamatera site. Explicit approval only.
# Safe to re-run: mirrors content and KEEPS SSL once the cert exists (never
# regresses HTTPS). First run on a fresh domain bootstraps HTTP -> webroot cert -> SSL.
set -euo pipefail
KAMATERA=root@45.61.58.125
SITE=gallery.agentabrams.com
HERE="$(cd "$(dirname "$0")/.." && pwd)"
# 1. DNS: ensure A record gallery -> Kamatera (DNS-only, fleet pattern)
export $(grep -E "^CLOUDFLARE_API_TOKEN=" ~/Projects/secrets-manager/.env)
ZONE=$(curl -s -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
"https://api.cloudflare.com/client/v4/zones?name=agentabrams.com" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['result'][0]['id'])")
EXISTS=$(curl -s -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
"https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records?name=$SITE" \
| python3 -c "import sys,json; print(len(json.load(sys.stdin)['result']))")
if [ "$EXISTS" = "0" ]; then
curl -s -X POST -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H "Content-Type: application/json" \
"https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-d "{\"type\":\"A\",\"name\":\"gallery\",\"content\":\"45.61.58.125\",\"ttl\":300,\"proxied\":false}" \
| python3 -c "import sys,json; r=json.load(sys.stdin); assert r['success'], r['errors']; print('DNS record created')"
else
echo "DNS record already exists"
fi
# 2. Content — mirror the repo (minus dev files) to the site root
rsync -az --delete --exclude .git --exclude deploy --exclude README.md "$HERE/" $KAMATERA:/var/www/$SITE/
echo "content rsynced (mirrored)"
# 3. nginx — install the RIGHT vhost for the current cert state (SSL-safe)
CERT="/etc/letsencrypt/live/$SITE/fullchain.pem"
if ssh $KAMATERA "test -f $CERT"; then
echo "cert present -> installing SSL vhost (keeping HTTPS)"
scp -q "$HERE/deploy/$SITE.ssl.nginx" $KAMATERA:/etc/nginx/sites-available/$SITE
ssh $KAMATERA "ln -sf /etc/nginx/sites-available/$SITE /etc/nginx/sites-enabled/$SITE && nginx -t && systemctl reload nginx"
else
echo "no cert yet -> HTTP bootstrap + webroot issuance"
scp -q "$HERE/deploy/$SITE.nginx" $KAMATERA:/etc/nginx/sites-available/$SITE
ssh $KAMATERA "ln -sf /etc/nginx/sites-available/$SITE /etc/nginx/sites-enabled/$SITE && nginx -t && systemctl reload nginx"
for i in $(seq 1 30); do [ -n "$(dig +short $SITE @1.1.1.1)" ] && break; sleep 10; done
ssh $KAMATERA "certbot certonly --webroot -w /var/www/$SITE -d $SITE --non-interactive --agree-tos -m steve@designerwallcoverings.com"
scp -q "$HERE/deploy/$SITE.ssl.nginx" $KAMATERA:/etc/nginx/sites-available/$SITE
ssh $KAMATERA "nginx -t && systemctl reload nginx"
fi
# 4. Smoke test
sleep 2
code=$(curl -s -o /dev/null -w '%{http_code}' https://$SITE/)
echo "https://$SITE -> HTTP $code"
curl -s https://$SITE/builds.json | head -c 200; echo
[ "$code" = "200" ] && echo "DEPLOY OK" || { echo "DEPLOY FAILED"; exit 1; }