gabriel / musehub public
setup-ec2-staging.sh bash
139 lines 5.8 KB
Raw
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor ⚠ breaking 1 day ago
1 #!/usr/bin/env bash
2 # Run this ON the staging EC2 instance (via SSH) after provisioning.
3 # Installs Docker and nginx, then configures the Cloudflare Origin Certificate.
4 # No Certbot or Let's Encrypt — Cloudflare terminates SSL at the edge.
5 #
6 # Prerequisites:
7 # 1. Generate a Cloudflare Origin Certificate for staging.musehub.ai:
8 # Cloudflare Dashboard → staging.musehub.ai → SSL/TLS → Origin Server
9 # → Create Certificate → RSA 2048 → 15 years
10 # Save certificate → /etc/ssl/cloudflare/origin.pem
11 # Save private key → /etc/ssl/cloudflare/origin.key
12 #
13 # 2. In Cloudflare: SSL/TLS → Overview → set mode to "Full (Strict)"
14 #
15 # Usage (from your Mac):
16 # scp -i ~/.ssh/musehub-key.pem -r deploy/ ubuntu@<STAGING_IP>:/home/ubuntu/
17 # # Copy cert files:
18 # scp -i ~/.ssh/musehub-key.pem origin.pem origin.key ubuntu@<STAGING_IP>:/home/ubuntu/
19 # ssh -i ~/.ssh/musehub-key.pem ubuntu@<STAGING_IP>
20 # chmod +x ~/deploy/setup-ec2-staging.sh && ~/deploy/setup-ec2-staging.sh
21 #
22 # After this script completes, sync the code and start the stack:
23 # rsync -az --exclude='.env' --exclude='node_modules/' --exclude='__pycache__/' \
24 # --exclude='.muse/' --exclude='*.pyc' \
25 # -e 'ssh -i ~/.ssh/musehub-key.pem' \
26 # ~/musehub/ ubuntu@<STAGING_IP>:/opt/musehub/
27 # ssh -i ~/.ssh/musehub-key.pem ubuntu@<STAGING_IP> \
28 # 'cd /opt/musehub && sudo docker compose up -d --build'
29
30 set -euo pipefail
31
32 DOMAIN="staging.musehub.ai"
33 APP_DIR="/opt/musehub"
34
35 echo "==> [1/7] System update"
36 sudo apt-get update -qq && sudo apt-get upgrade -y -qq
37
38 echo "==> [2/7] Install Docker"
39 curl -fsSL https://get.docker.com | sudo sh
40 sudo usermod -aG docker ubuntu
41 echo " Docker installed."
42
43 echo "==> [3/7] Install nginx"
44 sudo apt-get install -y -qq nginx
45
46 echo "==> [4/7] Install Cloudflare Origin Certificate"
47 sudo mkdir -p /etc/ssl/cloudflare
48
49 # Copy certs from home dir if present (scp'd in before running this script)
50 if [ -f ~/origin.pem ] && [ -f ~/origin.key ]; then
51 sudo cp ~/origin.pem /etc/ssl/cloudflare/origin.pem
52 sudo cp ~/origin.key /etc/ssl/cloudflare/origin.key
53 sudo chmod 644 /etc/ssl/cloudflare/origin.pem
54 sudo chmod 640 /etc/ssl/cloudflare/origin.key
55 sudo chown root:root /etc/ssl/cloudflare/origin.pem /etc/ssl/cloudflare/origin.key
56 echo " Origin certificate installed."
57 else
58 echo ""
59 echo " !! CERT FILES NOT FOUND — install them manually before nginx will start:"
60 echo " scp origin.pem origin.key ubuntu@<IP>:/home/ubuntu/"
61 echo " sudo cp ~/origin.pem /etc/ssl/cloudflare/origin.pem"
62 echo " sudo cp ~/origin.key /etc/ssl/cloudflare/origin.key"
63 echo " sudo chmod 640 /etc/ssl/cloudflare/origin.key"
64 echo " sudo nginx -s reload"
65 echo ""
66 fi
67
68 echo "==> [5/7] Configure nginx"
69
70 # Blue-green active-port file: deploy.sh rewrites this and does nginx -s reload
71 # to switch slots with zero downtime. Starts pointing at blue (1337).
72 echo "server 127.0.0.1:1337;" | sudo tee /etc/nginx/musehub-active-port > /dev/null
73
74 # Install the Cloudflare-ready nginx config, substituting the domain
75 sudo sed "s/DOMAIN_PLACEHOLDER/$DOMAIN/g" \
76 "$(dirname "$0")/nginx-cf.conf" \
77 | sudo tee /etc/nginx/sites-available/musehub-staging > /dev/null
78
79 sudo ln -sf /etc/nginx/sites-available/musehub-staging /etc/nginx/sites-enabled/musehub-staging
80 sudo rm -f /etc/nginx/sites-enabled/default
81 sudo nginx -t
82 sudo systemctl reload nginx
83 echo " nginx configured for $DOMAIN"
84
85 echo "==> [6/7] Create app directory"
86 sudo mkdir -p "$APP_DIR"
87 sudo chown ubuntu:ubuntu "$APP_DIR"
88 echo " $APP_DIR ready (code will be rsynced from your Mac)"
89
90 echo "==> [7/7] Create staging .env"
91 if [ ! -f "$APP_DIR/.env" ]; then
92 DB_PASSWORD=$(openssl rand -hex 16)
93 WEBHOOK_SECRET_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" 2>/dev/null || openssl rand -base64 32)
94 RUNNER_TOKEN=$(openssl rand -hex 32)
95
96 cat > "$APP_DIR/.env" << EOF
97 DEBUG=false
98 DATABASE_URL=postgresql+asyncpg://musehub:${DB_PASSWORD}@postgres:5432/musehub
99 DB_PASSWORD=${DB_PASSWORD}
100 CORS_ORIGINS=["https://staging.musehub.ai"]
101 WEBHOOK_SECRET_KEY=${WEBHOOK_SECRET_KEY}
102 MUSEHUB_ALLOWED_ORIGINS=["staging.musehub.ai"]
103 RUNNER_TOKEN=${RUNNER_TOKEN}
104 EOF
105 echo " .env created"
106 echo ""
107 echo " !! SAVE THESE — they are in $APP_DIR/.env !!"
108 cat "$APP_DIR/.env"
109 echo ""
110 else
111 echo " .env already exists, skipping"
112 fi
113
114 echo ""
115 echo "============================================================"
116 echo " STAGING SETUP COMPLETE"
117 echo "============================================================"
118 echo " Domain : https://$DOMAIN"
119 echo " App dir : $APP_DIR"
120 echo " Secrets : $APP_DIR/.env (back these up!)"
121 echo ""
122 echo " Next: sync code from your Mac and start the stack:"
123 echo " rsync -az --exclude='.env' --exclude='node_modules/' --exclude='__pycache__/' \\"
124 echo " --exclude='.muse/' --exclude='*.pyc' \\"
125 echo " -e 'ssh -i ~/.ssh/musehub-key.pem' \\"
126 echo " ~/musehub/ ubuntu@\$(hostname -I | awk '{print \$1}'):/opt/musehub/"
127 echo ""
128 echo " cd /opt/musehub && sudo docker compose up -d postgres musehub-runner"
129 echo " sudo docker compose build musehub"
130 echo " sudo docker compose run --rm --no-deps musehub alembic upgrade head"
131 echo " sudo docker run -d --name musehub-blue --network musehub-internal \\"
132 echo " --env-file .env -e SKIP_MIGRATIONS=1 \\"
133 echo " -e DATABASE_URL=postgresql+asyncpg://musehub:\$(grep ^DB_PASSWORD .env | cut -d= -f2)@postgres:5432/musehub \\"
134 echo " -v musehub_data:/data -p 127.0.0.1:1337:1337 --restart unless-stopped musehub/musehub"
135 echo " bash deploy/deploy.sh --init # sets .active-slot=blue"
136 echo ""
137 echo " Subsequent deploys (zero downtime):"
138 echo " rsync ... && bash deploy/deploy.sh"
139 echo "============================================================"
File History 1 commit
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor 1 day ago