gabriel / musehub public
setup-ec2.sh bash
110 lines 3.8 KB
7f1d07e8 feat: domains, MCP expansion, MIDI player, and production hardening (#8) Gabriel Cardona <cgcardona@gmail.com> 4d ago
1 #!/usr/bin/env bash
2 # Run this ON the EC2 instance (via SSH) after provisioning.
3 # Installs Docker, nginx, Certbot, deploys MuseHub, and obtains SSL.
4 #
5 # Usage (from your Mac, after DNS has propagated):
6 # scp -i ~/.ssh/musehub-key.pem -r deploy/ ubuntu@musehub.ai:/home/ubuntu/
7 # ssh -i ~/.ssh/musehub-key.pem ubuntu@musehub.ai
8 # chmod +x ~/deploy/setup-ec2.sh && ~/deploy/setup-ec2.sh
9
10 set -euo pipefail
11
12 DOMAIN="musehub.ai"
13 APP_DIR="/opt/musehub"
14 REPO_URL="https://github.com/cgcardona/musehub.git" # update to your actual repo URL
15
16 echo "==> [1/8] System update"
17 sudo apt-get update -qq && sudo apt-get upgrade -y -qq
18
19 echo "==> [2/8] Install Docker"
20 curl -fsSL https://get.docker.com | sudo sh
21 sudo usermod -aG docker ubuntu
22 echo " Docker installed. NOTE: You may need to log out/in for group to take effect."
23 echo " For this script we use 'sudo docker' throughout."
24
25 echo "==> [3/8] Install nginx + Certbot"
26 sudo apt-get install -y -qq nginx python3-certbot-nginx
27
28 echo "==> [4/8] Configure nginx (HTTP only for now — Certbot will add SSL)"
29 sudo tee /etc/nginx/sites-available/musehub > /dev/null << 'NGINX_CONF'
30 server {
31 listen 80;
32 listen [::]:80;
33 server_name musehub.ai www.musehub.ai;
34
35 client_max_body_size 50m;
36
37 location / {
38 proxy_pass http://127.0.0.1:10003;
39 proxy_http_version 1.1;
40 proxy_set_header Host $host;
41 proxy_set_header X-Real-IP $remote_addr;
42 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
43 proxy_set_header X-Forwarded-Proto $scheme;
44 proxy_read_timeout 60s;
45 }
46 }
47 NGINX_CONF
48
49 sudo ln -sf /etc/nginx/sites-available/musehub /etc/nginx/sites-enabled/musehub
50 sudo rm -f /etc/nginx/sites-enabled/default
51 sudo nginx -t
52 sudo systemctl reload nginx
53 echo " nginx configured"
54
55 echo "==> [5/8] Clone MuseHub repo"
56 sudo git clone "$REPO_URL" "$APP_DIR"
57 sudo chown -R ubuntu:ubuntu "$APP_DIR"
58 echo " Cloned to $APP_DIR"
59
60 echo "==> [6/8] Create production .env"
61 if [ ! -f "$APP_DIR/.env" ]; then
62 ACCESS_TOKEN_SECRET=$(openssl rand -hex 32)
63 DB_PASSWORD=$(openssl rand -hex 16)
64 WEBHOOK_SECRET_KEY=$(python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" 2>/dev/null || echo "GENERATE_ME_WITH_FERNET")
65
66 cat > "$APP_DIR/.env" << EOF
67 DEBUG=false
68 DATABASE_URL=postgresql+asyncpg://musehub:${DB_PASSWORD}@postgres:5432/musehub
69 DB_PASSWORD=${DB_PASSWORD}
70 ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
71 CORS_ORIGINS=["https://musehub.ai", "https://www.musehub.ai"]
72 WEBHOOK_SECRET_KEY=${WEBHOOK_SECRET_KEY}
73 MUSEHUB_ALLOWED_ORIGINS=["musehub.ai", "www.musehub.ai"]
74 EOF
75 echo " .env created with generated secrets"
76 echo ""
77 echo " !! SAVE THESE — they are in $APP_DIR/.env !!"
78 cat "$APP_DIR/.env"
79 echo ""
80 else
81 echo " .env already exists, skipping generation"
82 fi
83
84 echo "==> [7/8] Start MuseHub with Docker Compose"
85 cd "$APP_DIR"
86 sudo docker compose -f docker-compose.yml up -d --build
87 echo " Waiting 15 seconds for containers to start..."
88 sleep 15
89 sudo docker compose -f docker-compose.yml ps
90 echo " MuseHub started"
91
92 echo "==> [8/8] Obtain Let's Encrypt SSL certificate"
93 echo " (DNS must be propagated to $DOMAIN for this to succeed)"
94 sudo certbot --nginx \
95 -d "$DOMAIN" -d "www.$DOMAIN" \
96 --non-interactive \
97 --agree-tos \
98 --redirect \
99 --email "hello@musehub.ai"
100
101 echo ""
102 echo "============================================================"
103 echo " SETUP COMPLETE"
104 echo "============================================================"
105 echo " https://$DOMAIN is live"
106 echo " App dir : $APP_DIR"
107 echo " Secrets : $APP_DIR/.env (back these up!)"
108 echo ""
109 echo " Next: run deploy/seed.sh to create your account + repos"
110 echo "============================================================"