- Multi-stage Dockerfile with Node.js 20 Alpine base - Production and development docker-compose configurations - Health check API endpoint for container monitoring - Build and deployment scripts with versioning support - Port 3000 configuration for nginx compatibility - Non-root user and security hardening - Resource limits and logging configuration - Package.json scripts for Docker operations This eliminates dependency conflicts and provides reproducible deployments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
178 lines
5.2 KiB
Bash
Executable File
178 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Docker deployment script for Black Canyon Tickets
|
|
# Usage: ./scripts/docker-deploy.sh [environment]
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
ENVIRONMENT="${1:-production}"
|
|
IMAGE_NAME="bct-whitelabel"
|
|
VERSION="${2:-latest}"
|
|
COMPOSE_FILE="docker-compose.prod.yml"
|
|
|
|
echo -e "${GREEN}🚀 Deploying Black Canyon Tickets${NC}"
|
|
echo -e "${YELLOW}Environment: ${ENVIRONMENT}${NC}"
|
|
echo -e "${YELLOW}Version: ${VERSION}${NC}"
|
|
|
|
# Function to check if required environment variables are set
|
|
check_env_vars() {
|
|
local required_vars=(
|
|
"PUBLIC_SUPABASE_URL"
|
|
"PUBLIC_SUPABASE_ANON_KEY"
|
|
"SUPABASE_SERVICE_ROLE_KEY"
|
|
"STRIPE_PUBLISHABLE_KEY"
|
|
"STRIPE_SECRET_KEY"
|
|
"STRIPE_WEBHOOK_SECRET"
|
|
"RESEND_API_KEY"
|
|
)
|
|
|
|
echo -e "${BLUE}🔍 Checking environment variables...${NC}"
|
|
local missing_vars=()
|
|
|
|
for var in "${required_vars[@]}"; do
|
|
if [ -z "${!var}" ]; then
|
|
missing_vars+=("$var")
|
|
fi
|
|
done
|
|
|
|
if [ ${#missing_vars[@]} -ne 0 ]; then
|
|
echo -e "${RED}❌ Missing required environment variables:${NC}"
|
|
for var in "${missing_vars[@]}"; do
|
|
echo -e " - $var"
|
|
done
|
|
echo -e "${YELLOW}💡 Please set these variables in your .env file or environment${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}✅ All required environment variables are set${NC}"
|
|
}
|
|
|
|
# Function to check if .env file exists
|
|
check_env_file() {
|
|
if [ ! -f ".env" ]; then
|
|
echo -e "${YELLOW}⚠️ No .env file found. Creating from environment variables...${NC}"
|
|
# You might want to create a template .env file here
|
|
echo -e "${YELLOW}💡 Please ensure all required environment variables are available${NC}"
|
|
else
|
|
echo -e "${GREEN}✅ .env file found${NC}"
|
|
fi
|
|
}
|
|
|
|
# Function to pull latest image
|
|
pull_image() {
|
|
echo -e "${BLUE}📥 Pulling latest image...${NC}"
|
|
if ! docker pull "${IMAGE_NAME}:${VERSION}" 2>/dev/null; then
|
|
echo -e "${YELLOW}⚠️ Could not pull image from registry. Using local image.${NC}"
|
|
fi
|
|
}
|
|
|
|
# Function to stop existing containers
|
|
stop_containers() {
|
|
echo -e "${BLUE}🛑 Stopping existing containers...${NC}"
|
|
docker-compose -f "$COMPOSE_FILE" down --remove-orphans || true
|
|
}
|
|
|
|
# Function to start containers
|
|
start_containers() {
|
|
echo -e "${BLUE}🔄 Starting containers...${NC}"
|
|
|
|
# Set the image version
|
|
export DOCKER_IMAGE_TAG="$VERSION"
|
|
|
|
# Start services
|
|
docker-compose -f "$COMPOSE_FILE" up -d
|
|
|
|
echo -e "${GREEN}✅ Containers started!${NC}"
|
|
}
|
|
|
|
# Function to wait for health check
|
|
wait_for_health() {
|
|
echo -e "${BLUE}🏥 Waiting for application to be healthy...${NC}"
|
|
local max_attempts=30
|
|
local attempt=1
|
|
|
|
while [ $attempt -le $max_attempts ]; do
|
|
if docker-compose -f "$COMPOSE_FILE" ps --services --filter "status=running" | grep -q "bct-app"; then
|
|
if docker-compose -f "$COMPOSE_FILE" exec -T bct-app node -e "const http=require('http');const options={hostname:'localhost',port:4321,path:'/api/health',timeout:2000};const req=http.request(options,(res)=>{process.exit(res.statusCode===200?0:1)});req.on('error',()=>{process.exit(1)});req.end();" 2>/dev/null; then
|
|
echo -e "${GREEN}✅ Application is healthy!${NC}"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo -e "${YELLOW}⏳ Waiting... (attempt $attempt/$max_attempts)${NC}"
|
|
sleep 10
|
|
((attempt++))
|
|
done
|
|
|
|
echo -e "${RED}❌ Application failed to become healthy${NC}"
|
|
return 1
|
|
}
|
|
|
|
# Function to show deployment status
|
|
show_status() {
|
|
echo -e "${GREEN}📊 Deployment Status:${NC}"
|
|
docker-compose -f "$COMPOSE_FILE" ps
|
|
|
|
echo -e "\n${GREEN}📋 Container Logs (last 20 lines):${NC}"
|
|
docker-compose -f "$COMPOSE_FILE" logs --tail=20 bct-app
|
|
|
|
echo -e "\n${GREEN}🌐 Application should be available at:${NC}"
|
|
echo -e "${BLUE} http://localhost:3000${NC}"
|
|
}
|
|
|
|
# Function to cleanup old images
|
|
cleanup() {
|
|
echo -e "${BLUE}🧹 Cleaning up old images...${NC}"
|
|
docker image prune -f || true
|
|
echo -e "${GREEN}✅ Cleanup complete${NC}"
|
|
}
|
|
|
|
# Main deployment process
|
|
main() {
|
|
echo -e "${GREEN}Starting deployment process...${NC}"
|
|
|
|
# Pre-deployment checks
|
|
check_env_file
|
|
check_env_vars
|
|
|
|
# Deployment steps
|
|
pull_image
|
|
stop_containers
|
|
start_containers
|
|
|
|
# Post-deployment verification
|
|
if wait_for_health; then
|
|
show_status
|
|
cleanup
|
|
echo -e "${GREEN}🎉 Deployment completed successfully!${NC}"
|
|
else
|
|
echo -e "${RED}💥 Deployment failed!${NC}"
|
|
echo -e "${YELLOW}📋 Check logs with: docker-compose -f $COMPOSE_FILE logs${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Handle script arguments
|
|
case "${1:-}" in
|
|
--help|-h)
|
|
echo "Usage: $0 [environment] [version]"
|
|
echo " environment: production (default)"
|
|
echo " version: Docker image tag (default: latest)"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Deploy latest to production"
|
|
echo " $0 production v1.2.3 # Deploy specific version"
|
|
exit 0
|
|
;;
|
|
*)
|
|
main
|
|
;;
|
|
esac |