← back to Norma Sdcc Pitch

DEPLOY-NOW.sh

134 lines

#!/usr/bin/env bash
# DEPLOY: sdcc.agentabrams.com — pitch viewer with SDCC login
# Run from your laptop. Idempotent.
set -e

DOMAIN="sdcc.agentabrams.com"
PORT="9877"
PROJ="$HOME/Projects/norma-sdcc-pitch"
REMOTE_PROJ="/root/Projects/norma-sdcc-pitch"
KAMATERA_IP="45.61.58.125"

SDCC_PASSWORD="${SDCC_PASSWORD:-Pulse-2026}"
STEVE_PASSWORD="${STEVE_PASSWORD:-DWSecure2024!}"
COOKIE_SECRET="${COOKIE_SECRET:-$(openssl rand -hex 32)}"

echo "── 1. Add DNS A record via GoDaddy ──"
source ~/Projects/secrets-manager/.env
# Prefer a Bearer Personal Access Token (TK-10 key rotation); fall back to legacy sso-key.
if [ -n "${GODADDY_PAT:-}" ]; then GD_AUTH="Bearer ${GODADDY_PAT}"; else GD_AUTH="sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}"; fi
curl -fsSX PUT "https://api.godaddy.com/v1/domains/agentabrams.com/records/A/sdcc" \
  -H "Authorization: ${GD_AUTH}" \
  -H "Content-Type: application/json" \
  -d "[{\"data\":\"${KAMATERA_IP}\",\"ttl\":600}]" \
  && echo "  ✓ DNS A record set"

echo
echo "── 2. rsync code to Kamatera ──"
rsync -aHz --delete \
  --exclude node_modules --exclude .git --exclude videos --exclude '*.log' \
  --exclude 'data/pitch-state' --exclude DEPLOY-NOW.sh \
  "${PROJ}/" my-server:"${REMOTE_PROJ}/"
echo "  ✓ code synced"

echo
echo "── 3. write .env on remote with login secrets ──"
ssh my-server "cat > ${REMOTE_PROJ}/.env <<ENV
PORT=${PORT}
SDCC_PASSWORD=${SDCC_PASSWORD}
STEVE_PASSWORD=${STEVE_PASSWORD}
COOKIE_SECRET=${COOKIE_SECRET}
NORMA_BASE=http://localhost:7400
NODE_ENV=production
ENV
chmod 600 ${REMOTE_PROJ}/.env
echo '  ✓ .env written'"

echo
echo "── 4. install deps + pm2 ──"
ssh my-server bash <<EOF
set -e
cd ${REMOTE_PROJ}
npm install --no-fund --no-audit --omit=dev 2>&1 | tail -3
# kill anything on :${PORT} first
fuser -k -n tcp ${PORT} 2>/dev/null || true
sleep 1
pm2 delete norma-sdcc-pitch 2>/dev/null || true
pm2 start server.js --name norma-sdcc-pitch --update-env --env production --node-args=""
pm2 save
sleep 2
pm2 list | grep norma-sdcc-pitch
EOF

echo
echo "── 5. nginx server block ──"
ssh my-server bash <<EOF
set -e
cat > /etc/nginx/sites-available/${DOMAIN} <<'NGINX'
server {
    listen 80;
    server_name DOMAIN_PLACEHOLDER;
    access_log /var/log/nginx/sdcc-pitch.access.log;
    error_log  /var/log/nginx/sdcc-pitch.error.log;

    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-Content-Type-Options nosniff always;
    add_header Referrer-Policy strict-origin-when-cross-origin always;

    location / {
        proxy_pass http://127.0.0.1:PORT_PLACEHOLDER;
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_read_timeout 60s;
    }
}
NGINX
sed -i "s/DOMAIN_PLACEHOLDER/${DOMAIN}/g; s/PORT_PLACEHOLDER/${PORT}/g" /etc/nginx/sites-available/${DOMAIN}
ln -sf /etc/nginx/sites-available/${DOMAIN} /etc/nginx/sites-enabled/${DOMAIN}
nginx -t && systemctl reload nginx
echo "  ✓ nginx serving ${DOMAIN}"
EOF

echo
echo "── 6. wait for DNS propagation ──"
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
  if dig +short ${DOMAIN} @1.1.1.1 | grep -q "${KAMATERA_IP}"; then
    echo "  ✓ DNS propagated"
    break
  fi
  if [ "$i" = "20" ]; then
    echo "  ! DNS still hasn't propagated to 1.1.1.1 — proceeding anyway, certbot may retry"
  fi
  printf "  …waiting (%d/20)\r" "$i"
  sleep 5
done

echo
echo "── 7. Let's Encrypt SSL ──"
ssh my-server "certbot --nginx -d ${DOMAIN} --non-interactive --agree-tos --register-unsafely-without-email --redirect 2>&1 | tail -8"

echo
echo "── 8. verify ──"
sleep 2
curl -sI --max-time 8 "https://${DOMAIN}/" 2>&1 | head -3

cat <<DONE

═══════════════════════════════════════════════════════════════
  LIVE → https://${DOMAIN}

  SDCC LOGIN:
    Username: sdcc
    Password: ${SDCC_PASSWORD}

  Steve LOGIN (full access):
    Username: steve
    Password: ${STEVE_PASSWORD}

═══════════════════════════════════════════════════════════════

DONE