398 lines
10 KiB
Bash
398 lines
10 KiB
Bash
#!/bin/bash
|
|
|
|
# VIP Coordinator - Simple Digital Ocean Deployment
|
|
# Designed for clean Docker droplets with optional SSL
|
|
|
|
set -e
|
|
|
|
clear
|
|
echo "🚀 VIP Coordinator - Simple Cloud Deployment"
|
|
echo "============================================="
|
|
echo ""
|
|
echo "This script deploys VIP Coordinator on a clean Digital Ocean droplet:"
|
|
echo " ✅ Uses standard ports (80/443 for web, 3000 for API)"
|
|
echo " ✅ Pre-built Docker Hub images"
|
|
echo " ✅ Optional SSL certificates with Let's Encrypt"
|
|
echo " ✅ Ready in under 5 minutes"
|
|
echo ""
|
|
|
|
# Function to prompt for input
|
|
prompt_input() {
|
|
local prompt="$1"
|
|
local var_name="$2"
|
|
|
|
while [ -z "${!var_name}" ]; do
|
|
read -p "$prompt: " input
|
|
if [ -n "$input" ]; then
|
|
eval "$var_name='$input'"
|
|
else
|
|
echo "This field is required. Please enter a value."
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Function to generate random password
|
|
generate_password() {
|
|
openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
|
|
}
|
|
|
|
echo "📋 Quick Configuration"
|
|
echo "====================="
|
|
echo ""
|
|
|
|
# Get server domain
|
|
echo "1. Server Configuration"
|
|
echo "----------------------"
|
|
prompt_input "Enter your main domain (e.g., mysite.com)" DOMAIN
|
|
prompt_input "Enter your API subdomain (e.g., api.mysite.com)" API_DOMAIN
|
|
prompt_input "Enter your email for SSL certificates" EMAIL
|
|
|
|
# Ask about SSL
|
|
echo ""
|
|
echo "2. SSL Certificate Setup"
|
|
echo "------------------------"
|
|
echo "Do you want to set up free SSL certificates with Let's Encrypt?"
|
|
echo " ✅ Automatic HTTPS setup"
|
|
echo " ✅ Uses certbot Docker container"
|
|
echo " ✅ Secure production deployment"
|
|
echo ""
|
|
read -p "Set up SSL certificates? [Y/n]: " setup_ssl
|
|
|
|
if [[ $setup_ssl =~ ^[Nn]$ ]]; then
|
|
USE_SSL=false
|
|
FRONTEND_URL="http://$DOMAIN"
|
|
API_URL="http://$API_DOMAIN"
|
|
FRONTEND_PORT="80:80"
|
|
else
|
|
USE_SSL=true
|
|
FRONTEND_URL="https://$DOMAIN"
|
|
API_URL="https://$API_DOMAIN"
|
|
FRONTEND_PORT="80:80"
|
|
fi
|
|
|
|
GOOGLE_REDIRECT_URI="$API_URL/auth/google/callback"
|
|
|
|
echo ""
|
|
echo "3. Google OAuth Setup"
|
|
echo "--------------------"
|
|
echo "Quick setup at: https://console.cloud.google.com/"
|
|
echo " 1. Create project → Enable Google+ API"
|
|
echo " 2. Credentials → OAuth 2.0 Client IDs"
|
|
echo " 3. Add redirect URI: $GOOGLE_REDIRECT_URI"
|
|
echo ""
|
|
|
|
prompt_input "Google OAuth Client ID" GOOGLE_CLIENT_ID
|
|
prompt_input "Google OAuth Client Secret" GOOGLE_CLIENT_SECRET
|
|
|
|
# Generate secure passwords
|
|
echo ""
|
|
echo "4. Generating secure passwords..."
|
|
DB_PASSWORD=$(generate_password)
|
|
ADMIN_PASSWORD=$(generate_password)
|
|
|
|
echo "✅ Configuration complete!"
|
|
echo ""
|
|
|
|
# Create .env file
|
|
cat > .env << EOF
|
|
# VIP Coordinator - Simple Deployment Configuration
|
|
# Generated on $(date)
|
|
|
|
# Database
|
|
DB_PASSWORD=$DB_PASSWORD
|
|
|
|
# Server Configuration
|
|
DOMAIN=$DOMAIN
|
|
API_DOMAIN=$API_DOMAIN
|
|
FRONTEND_URL=$FRONTEND_URL
|
|
VITE_API_URL=$API_URL
|
|
|
|
# Google OAuth
|
|
GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID
|
|
GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
|
|
GOOGLE_REDIRECT_URI=$GOOGLE_REDIRECT_URI
|
|
|
|
# Admin
|
|
ADMIN_PASSWORD=$ADMIN_PASSWORD
|
|
|
|
# SSL
|
|
USE_SSL=$USE_SSL
|
|
EMAIL=$EMAIL
|
|
EOF
|
|
|
|
# Create compose.yaml (Docker Compose v2 format)
|
|
cat > compose.yaml << EOF
|
|
version: '3.8'
|
|
|
|
services:
|
|
db:
|
|
image: postgres:15
|
|
environment:
|
|
POSTGRES_DB: vip_coordinator
|
|
POSTGRES_PASSWORD: \${DB_PASSWORD}
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:7
|
|
restart: unless-stopped
|
|
|
|
backend:
|
|
image: t72chevy/vip-coordinator:backend-latest
|
|
environment:
|
|
DATABASE_URL: postgresql://postgres:\${DB_PASSWORD}@db:5432/vip_coordinator
|
|
REDIS_URL: redis://redis:6379
|
|
GOOGLE_CLIENT_ID: \${GOOGLE_CLIENT_ID}
|
|
GOOGLE_CLIENT_SECRET: \${GOOGLE_CLIENT_SECRET}
|
|
GOOGLE_REDIRECT_URI: \${GOOGLE_REDIRECT_URI}
|
|
FRONTEND_URL: \${FRONTEND_URL}
|
|
ADMIN_PASSWORD: \${ADMIN_PASSWORD}
|
|
PORT: 3000
|
|
ports:
|
|
- "3000:3000"
|
|
depends_on:
|
|
- db
|
|
- redis
|
|
restart: unless-stopped
|
|
|
|
frontend:
|
|
image: t72chevy/vip-coordinator:frontend-latest
|
|
ports:
|
|
- "$FRONTEND_PORT"
|
|
volumes:
|
|
- ./webroot:/usr/share/nginx/html/.well-known
|
|
depends_on:
|
|
- backend
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
postgres-data:
|
|
EOF
|
|
|
|
# SSL Certificate Setup
|
|
if [ "$USE_SSL" = "true" ]; then
|
|
echo ""
|
|
echo "🔒 Setting up SSL certificates..."
|
|
echo "================================"
|
|
|
|
# Create webroot directory for Let's Encrypt validation
|
|
mkdir -p webroot
|
|
|
|
# Start the application first to serve the webroot
|
|
echo "📋 Starting application for SSL validation..."
|
|
docker compose up -d
|
|
sleep 10
|
|
|
|
echo "📋 Generating Let's Encrypt certificates for $DOMAIN and $API_DOMAIN..."
|
|
echo "This may take a few minutes..."
|
|
|
|
# Run certbot using webroot method with the exact command format you provided
|
|
docker run -it --rm \
|
|
-v /etc/letsencrypt:/etc/letsencrypt \
|
|
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
|
|
-v $(pwd)/webroot:/data/letsencrypt \
|
|
certbot/certbot certonly \
|
|
--webroot -w /data/letsencrypt \
|
|
-d $DOMAIN -d $API_DOMAIN \
|
|
--email $EMAIL --agree-tos --no-eff-email
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "✅ SSL certificates generated successfully!"
|
|
|
|
# Create nginx SSL configuration
|
|
cat > nginx-ssl.conf << EOF
|
|
# Nginx SSL Configuration for VIP Coordinator
|
|
# Copy to /etc/nginx/sites-available/vip-coordinator
|
|
|
|
# Redirect HTTP to HTTPS
|
|
server {
|
|
listen 80;
|
|
server_name $DOMAIN $API_DOMAIN;
|
|
|
|
# Let's Encrypt validation
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/html;
|
|
}
|
|
|
|
# Redirect everything else to HTTPS
|
|
location / {
|
|
return 301 https://\$server_name\$request_uri;
|
|
}
|
|
}
|
|
|
|
# Frontend with SSL
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name $DOMAIN;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
|
|
|
# SSL settings
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
|
ssl_prefer_server_ciphers off;
|
|
|
|
# Security headers
|
|
add_header Strict-Transport-Security "max-age=31536000" always;
|
|
add_header X-Frame-Options DENY always;
|
|
add_header X-Content-Type-Options nosniff always;
|
|
|
|
location / {
|
|
proxy_pass http://localhost:80;
|
|
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;
|
|
}
|
|
}
|
|
|
|
# Backend API with SSL
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name $API_DOMAIN;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
|
|
|
# SSL settings
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
|
ssl_prefer_server_ciphers off;
|
|
|
|
location / {
|
|
proxy_pass http://localhost:3000;
|
|
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;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Create certificate renewal script
|
|
cat > renew-ssl.sh << EOF
|
|
#!/bin/bash
|
|
echo "🔄 Renewing SSL certificates..."
|
|
|
|
# Renew certificates using the same webroot method
|
|
docker run -it --rm \\
|
|
-v /etc/letsencrypt:/etc/letsencrypt \\
|
|
-v /var/lib/letsencrypt:/var/lib/letsencrypt \\
|
|
-v \$(pwd)/webroot:/data/letsencrypt \\
|
|
certbot/certbot renew \\
|
|
--webroot -w /data/letsencrypt
|
|
|
|
# Reload nginx if it's running
|
|
if systemctl is-active --quiet nginx; then
|
|
systemctl reload nginx
|
|
echo "✅ Nginx reloaded with new certificates"
|
|
fi
|
|
|
|
echo "✅ Certificate renewal completed"
|
|
EOF
|
|
|
|
chmod +x renew-ssl.sh
|
|
|
|
echo ""
|
|
echo "📄 SSL files generated:"
|
|
echo " - nginx-ssl.conf (nginx configuration)"
|
|
echo " - renew-ssl.sh (renewal script)"
|
|
echo ""
|
|
echo "🔧 To complete SSL setup:"
|
|
echo " 1. Install nginx: apt update && apt install nginx"
|
|
echo " 2. Copy config: cp nginx-ssl.conf /etc/nginx/sites-available/vip-coordinator"
|
|
echo " 3. Enable site: ln -s /etc/nginx/sites-available/vip-coordinator /etc/nginx/sites-enabled/"
|
|
echo " 4. Remove default: rm /etc/nginx/sites-enabled/default"
|
|
echo " 5. Test config: nginx -t"
|
|
echo " 6. Restart nginx: systemctl restart nginx"
|
|
echo " 7. Set up auto-renewal: echo '0 3 1 * * /path/to/renew-ssl.sh' | crontab -"
|
|
|
|
else
|
|
echo "❌ SSL certificate generation failed"
|
|
echo "Continuing with HTTP setup..."
|
|
USE_SSL=false
|
|
fi
|
|
fi
|
|
|
|
# Create management scripts
|
|
cat > start.sh << 'EOF'
|
|
#!/bin/bash
|
|
echo "🚀 Starting VIP Coordinator..."
|
|
docker compose pull
|
|
docker compose up -d
|
|
sleep 10
|
|
echo ""
|
|
echo "🎉 VIP Coordinator is running!"
|
|
echo "=============================="
|
|
docker compose ps
|
|
EOF
|
|
|
|
chmod +x start.sh
|
|
|
|
cat > stop.sh << 'EOF'
|
|
#!/bin/bash
|
|
echo "🛑 Stopping VIP Coordinator..."
|
|
docker compose down
|
|
echo "✅ Stopped."
|
|
EOF
|
|
|
|
chmod +x stop.sh
|
|
|
|
cat > status.sh << EOF
|
|
#!/bin/bash
|
|
echo "📊 VIP Coordinator Status"
|
|
echo "========================="
|
|
docker compose ps
|
|
echo ""
|
|
echo "🌐 Access URLs:"
|
|
echo " Frontend: $FRONTEND_URL"
|
|
echo " Backend API: $API_URL"
|
|
EOF
|
|
|
|
chmod +x status.sh
|
|
|
|
echo ""
|
|
echo "✅ Simple deployment ready!"
|
|
echo "=========================="
|
|
echo ""
|
|
echo "Generated files:"
|
|
echo " 📄 .env - Configuration"
|
|
echo " 📄 compose.yaml - Services"
|
|
echo " 📄 start.sh - Start everything"
|
|
echo " 📄 stop.sh - Stop everything"
|
|
echo " 📄 status.sh - Check status"
|
|
|
|
if [ "$USE_SSL" = "true" ]; then
|
|
echo " 🔒 nginx-ssl.conf - SSL configuration"
|
|
echo " 🔒 renew-ssl.sh - Certificate renewal"
|
|
fi
|
|
|
|
echo ""
|
|
echo "🚀 To start VIP Coordinator:"
|
|
echo " ./start.sh"
|
|
echo ""
|
|
echo "🌐 Access your application:"
|
|
echo " Frontend: $FRONTEND_URL"
|
|
echo " Backend API: $API_URL"
|
|
echo ""
|
|
echo "🔑 Important credentials:"
|
|
echo " Admin password: $ADMIN_PASSWORD"
|
|
echo " Database password: $DB_PASSWORD"
|
|
echo ""
|
|
echo "💡 First time setup:"
|
|
echo " 1. Run: ./start.sh"
|
|
echo " 2. Open: $FRONTEND_URL"
|
|
echo " 3. Login with Google to become admin"
|
|
|
|
if [ "$USE_SSL" = "true" ]; then
|
|
echo ""
|
|
echo "🔒 SSL Setup Complete!"
|
|
echo " - Certificates generated for $DOMAIN and $API_DOMAIN"
|
|
echo " - Configure nginx with nginx-ssl.conf"
|
|
echo " - Set up monthly renewal with renew-ssl.sh"
|
|
fi
|
|
|
|
echo ""
|
|
echo "🎉 Ready to deploy on Digital Ocean!" |