modcomms/deploy.sh
michael 3df1b9fb92 Auto-generate .env for docker compose commands
The deploy script now creates a .env file with COMPOSE_PROJECT_NAME
and BACKEND_PORT so that manual docker compose commands (ps, logs, etc.)
work without needing to set environment variables.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 06:37:41 -06:00

174 lines
4.8 KiB
Bash
Executable file

#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "=== ModComms Deployment ==="
echo "Working directory: $SCRIPT_DIR"
# --- Check prerequisites ---
echo ""
echo "[Prerequisites] Checking required tools..."
check_command() {
if ! command -v "$1" &> /dev/null; then
echo "Error: $1 is not installed"
exit 1
fi
echo "$1"
}
check_command git
check_command node
check_command npm
check_command docker
# --- Load deployment configuration ---
if [ -f .env.deploy ]; then
source .env.deploy
echo " ✓ .env.deploy loaded"
else
echo ""
echo "Error: .env.deploy not found"
echo "Create it from the template:"
echo " cp .env.deploy.example .env.deploy"
echo " nano .env.deploy"
exit 1
fi
# Validate required variables
if [ -z "$FRONTEND_DEPLOY_DIR" ]; then
echo "Error: FRONTEND_DEPLOY_DIR not set in .env.deploy"
exit 1
fi
# Set defaults for docker compose variables
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-modcomms}"
BACKEND_PORT="${BACKEND_PORT:-8000}"
echo " Environment: ${COMPOSE_PROJECT_NAME} (port ${BACKEND_PORT})"
# Create .env file for docker compose (so manual docker compose commands work)
cat > .env << EOF
# Auto-generated by deploy.sh - do not edit manually
# Edit .env.deploy instead and re-run deploy.sh
COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME}
BACKEND_PORT=${BACKEND_PORT}
EOF
echo " ✓ .env created for docker compose"
# --- Check backend/.env exists (required for GEMINI_API_KEY) ---
if [ ! -f backend/.env ]; then
if [ -f backend/.env.example ]; then
echo ""
echo "Error: backend/.env not found"
echo "Create it from the template:"
echo " cp backend/.env.example backend/.env"
echo " nano backend/.env # Add your GEMINI_API_KEY"
exit 1
else
echo "Error: backend/.env not found and no template available"
exit 1
fi
fi
echo " ✓ backend/.env exists"
# --- 1. Pull latest code (skip if not a git repo or no remote) ---
echo ""
echo "[1/5] Updating code..."
if [ -d .git ]; then
if git remote -v | grep -q origin; then
git pull || echo "Warning: git pull failed, continuing with local code"
else
echo " No remote configured, skipping git pull"
fi
else
echo " Not a git repository, skipping git pull"
fi
# --- 2. Build frontend ---
echo ""
echo "[2/5] Building frontend..."
cd frontend
# Install dependencies (npm install is idempotent)
npm install
# Create/update .env.local with production URLs
cat > .env.local << EOF
VITE_BACKEND_WS_URL=${VITE_BACKEND_WS_URL:-ws://localhost:8000/ws/analyze}
VITE_BACKEND_URL=${VITE_BACKEND_URL:-http://localhost:8000}
EOF
echo " Frontend environment configured"
npm run build
cd "$SCRIPT_DIR"
# --- 3. Deploy frontend to Apache ---
echo ""
echo "[3/5] Deploying frontend to ${FRONTEND_DEPLOY_DIR}..."
# Create directory if it doesn't exist
sudo mkdir -p "$FRONTEND_DEPLOY_DIR"
# Clear existing files (safe deletion with variable check)
if [ -n "$FRONTEND_DEPLOY_DIR" ] && [ -d "$FRONTEND_DEPLOY_DIR" ]; then
sudo find "$FRONTEND_DEPLOY_DIR" -mindepth 1 -delete 2>/dev/null || true
fi
# Copy new build
sudo cp -r frontend/dist/* "$FRONTEND_DEPLOY_DIR/"
sudo chown -R www-data:www-data "$FRONTEND_DEPLOY_DIR"
echo " ✓ Frontend deployed"
# --- 4. Update backend configuration ---
echo ""
echo "[4/5] Updating backend configuration..."
# Update CORS_ORIGINS if specified
if [ -n "$CORS_ORIGINS" ]; then
if grep -q "^CORS_ORIGINS=" backend/.env; then
sed -i "s|^CORS_ORIGINS=.*|CORS_ORIGINS=${CORS_ORIGINS}|" backend/.env
else
echo "CORS_ORIGINS=${CORS_ORIGINS}" >> backend/.env
fi
echo " ✓ CORS_ORIGINS updated"
fi
# --- 5. Build and start/restart backend containers ---
echo ""
echo "[5/5] Building and starting backend..."
# Build image (always rebuild to pick up code changes)
docker compose build
# Start or restart containers (docker compose up -d is idempotent)
docker compose up -d
# Wait for health check
echo " Waiting for backend to be healthy..."
for i in {1..30}; do
if curl -sf "http://localhost:${BACKEND_PORT}/health" > /dev/null 2>&1; then
echo " ✓ Backend is healthy"
break
fi
if [ $i -eq 30 ]; then
echo " Warning: Backend health check timed out"
fi
sleep 1
done
# --- Deployment summary ---
echo ""
echo "========================================="
echo " Deployment Complete!"
echo "========================================="
echo ""
echo "Environment: ${COMPOSE_PROJECT_NAME}"
echo "Frontend: ${FRONTEND_DEPLOY_DIR}"
echo "Backend: http://localhost:${BACKEND_PORT}"
echo ""
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "Health check:"
curl -s "http://localhost:${BACKEND_PORT}/health" && echo "" || echo "Warning: Backend not responding"