#!/bin/bash # ========================================== # CoopCredits Production Deployment Script # For infrastructure: 172.20.1.0/24 # ========================================== set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' echo -e "${BLUE}" echo "🚀 CoopCredits Production Deployment" echo "====================================" echo -e "${NC}" echo "Time: $(date)" echo "Project: $PROJECT_DIR" echo "" # ========================================== # Pre-deployment Checks # ========================================== pre_deployment_checks() { echo -e "${BLUE}Running pre-deployment checks...${NC}" # Check environment file if [ ! -f "$PROJECT_DIR/.env" ]; then echo -e "${RED}❌ .env file not found!${NC}" echo "Run: ./deployment/setup-infrastructure.sh" exit 1 fi # Check SSL certificates if [ ! -f "$PROJECT_DIR/docker/nginx/ssl/cert.pem" ] && [ ! -d "$PROJECT_DIR/docker/nginx/letsencrypt" ]; then echo -e "${YELLOW}⚠️ SSL certificates not found${NC}" echo "Place certificates in docker/nginx/ssl/ or setup Let's Encrypt" read -p "Continue without SSL? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi # Check Docker if ! command -v docker &> /dev/null; then echo -e "${RED}❌ Docker not installed${NC}" exit 1 fi if ! command -v docker-compose &> /dev/null; then echo -e "${RED}❌ Docker Compose not installed${NC}" exit 1 fi # Check required env variables source "$PROJECT_DIR/.env" local required_vars=( "JWT_SECRET" "TAUTULLI_API_KEY" "OVERSEER_API_KEY" "SOLANA_MINT_AUTHORITY_KEYPAIR" "ENCRYPTION_KEY" ) local missing=0 for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then echo -e "${RED}❌ Missing required environment variable: $var${NC}" missing=1 fi done if [ $missing -eq 1 ]; then echo "Please edit $PROJECT_DIR/.env and add the missing values" exit 1 fi echo -e "${GREEN}✅ Pre-deployment checks passed${NC}" echo "" } # ========================================== # Backup Current State # ========================================== backup_state() { echo -e "${BLUE}Creating backup...${NC}" local backup_dir="$PROJECT_DIR/backups/$(date +%Y%m%d_%H%M%S)" mkdir -p "$backup_dir" # Backup database if running if docker ps | grep -q "coop-postgres"; then echo "Backing up database..." docker exec coop-postgres pg_dump -U coop coop_credits > "$backup_dir/database.sql" 2>/dev/null || true fi # Backup environment cp "$PROJECT_DIR/.env" "$backup_dir/" # Backup Docker volumes list docker volume ls | grep coop > "$backup_dir/volumes.txt" 2>/dev/null || true echo -e "${GREEN}✅ Backup created: $backup_dir${NC}" echo "" } # ========================================== # Build and Deploy # ========================================== deploy() { echo -e "${BLUE}Building and deploying...${NC}" cd "$PROJECT_DIR" # Pull latest images echo "Pulling base images..." docker-compose -f docker-compose.prod.yml pull # Build services echo "Building services..." docker-compose -f docker-compose.prod.yml build --no-cache # Stop existing services echo "Stopping existing services..." docker-compose -f docker-compose.prod.yml down --remove-orphans # Start services echo "Starting services..." docker-compose -f docker-compose.prod.yml up -d # Wait for database echo "Waiting for database..." sleep 10 # Run migrations echo "Running database migrations..." docker-compose -f docker-compose.prod.yml exec -T backend npx prisma migrate deploy || { echo -e "${YELLOW}⚠️ Migration may have already been applied${NC}" } # Seed initial data if needed echo "Checking for initial data..." docker-compose -f docker-compose.prod.yml exec -T backend npx prisma db seed 2>/dev/null || true echo -e "${GREEN}✅ Deployment complete!${NC}" echo "" } # ========================================== # Post-deployment Verification # ========================================== verify_deployment() { echo -e "${BLUE}Verifying deployment...${NC}" local retries=30 local delay=2 # Wait for services to be ready echo "Waiting for services to start..." for i in $(seq 1 $retries); do if curl -sf https://coop.hobokenchicken.com/health > /dev/null 2>&1; then echo -e "${GREEN}✅ Website is responding${NC}" break fi if [ $i -eq $retries ]; then echo -e "${RED}❌ Website failed to start${NC}" echo "Check logs: docker-compose -f docker-compose.prod.yml logs" exit 1 fi echo -n "." sleep $delay done # Check database connection if docker-compose -f docker-compose.prod.yml exec -T postgres pg_isready -U coop > /dev/null 2>&1; then echo -e "${GREEN}✅ Database is ready${NC}" else echo -e "${RED}❌ Database not responding${NC}" fi echo "" } # ========================================== # Display Info # ========================================== show_info() { echo -e "${BLUE}Deployment Information${NC}" echo "======================" echo "" echo "Website: https://coop.hobokenchicken.com" echo "API: https://coop.hobokenchicken.com/api" echo "Webhooks: https://coop.hobokenchicken.com/webhooks/" echo "" echo "Services:" docker-compose -f "$PROJECT_DIR/docker-compose.prod.yml" ps echo "" echo "Useful commands:" echo " View logs: docker-compose -f docker-compose.prod.yml logs -f" echo " Stop: docker-compose -f docker-compose.prod.yml down" echo " Restart: docker-compose -f docker-compose.prod.yml restart" echo " Health check: ./deployment/health-check.sh" echo "" echo -e "${GREEN}🎉 Deployment successful!${NC}" } # ========================================== # Main # ========================================== main() { pre_deployment_checks backup_state deploy verify_deployment show_info } # Handle script arguments case "${1:-}" in --check) pre_deployment_checks exit 0 ;; --backup) backup_state exit 0 ;; --help|-h) echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --check Run pre-deployment checks only" echo " --backup Create backup only" echo " --help Show this help message" echo "" exit 0 ;; *) main ;; esac