File size: 13,635 Bytes
c293f7c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | #!/bin/bash
# Docker Production Environment Management Script
# Provides commands for managing the production Docker environment
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
print_header() {
echo -e "${PURPLE}================================${NC}"
echo -e "${PURPLE}$1${NC}"
echo -e "${PURPLE}================================${NC}"
}
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
show_usage() {
echo "Usage: $0 [COMMAND]"
echo ""
echo "Commands:"
echo " build Build production Docker images"
echo " deploy Deploy to production environment"
echo " update Update production deployment"
echo " rollback Rollback to previous version"
echo " stop Stop production environment"
echo " logs Show logs from production services"
echo " status Show status of production services"
echo " health Check health of production services"
echo " backup Create backup of production data"
echo " restore Restore from backup"
echo " scale Scale services up/down"
echo " clean Clean up old images and containers"
echo ""
echo "Examples:"
echo " $0 build # Build production images"
echo " $0 deploy # Deploy to production"
echo " $0 scale app=3 # Scale app service to 3 replicas"
echo " $0 logs app # Show logs from app service"
}
check_prerequisites() {
print_status "Checking production prerequisites..."
if ! command -v docker &> /dev/null; then
print_error "Docker is not installed."
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
print_error "Docker Compose is not installed."
exit 1
fi
# Check if production .env file exists
if [[ ! -f .env.production ]]; then
print_error ".env.production file not found."
print_status "Please create .env.production with production configuration"
exit 1
fi
# Check for SSL certificates
if [[ ! -f "${SSL_CERT_PATH:-./ssl/cert.pem}" ]]; then
print_warning "SSL certificate not found. HTTPS will not work."
fi
# Check for Google Cloud credentials
if [[ ! -f "${GOOGLE_APPLICATION_CREDENTIALS_FILE:-./credentials.json}" ]]; then
print_warning "Google Cloud credentials not found."
fi
print_success "Prerequisites check completed"
}
build_production_images() {
print_header "Building Production Docker Images"
# Set production environment
export BUILD_TARGET=production
export VERSION=${VERSION:-$(date +%Y%m%d-%H%M%S)}
# Build with version tag
docker-compose -f docker-compose.prod.yml build --no-cache
# Tag with version
docker tag misinformation-heatmap:latest misinformation-heatmap:$VERSION
print_success "Production images built with version: $VERSION"
}
deploy_production() {
print_header "Deploying to Production Environment"
# Load production environment
set -a
source .env.production
set +a
export BUILD_TARGET=production
export COMPOSE_PROFILES=production,monitoring
# Pre-deployment checks
print_status "Running pre-deployment checks..."
# Check if required environment variables are set
required_vars=("GOOGLE_CLOUD_PROJECT" "API_KEYS" "GRAFANA_PASSWORD")
for var in "${required_vars[@]}"; do
if [[ -z "${!var}" ]]; then
print_error "Required environment variable $var is not set"
exit 1
fi
done
# Create necessary directories
mkdir -p data logs ssl
# Deploy services
print_status "Starting production services..."
docker-compose -f docker-compose.prod.yml up -d
# Wait for services to be healthy
print_status "Waiting for services to be healthy..."
sleep 30
# Health check
if check_production_health; then
print_success "Production deployment completed successfully"
print_status "Services available at:"
print_status " - Application: https://localhost"
print_status " - Monitoring: http://localhost:3001"
print_status " - Metrics: http://localhost:9090"
else
print_error "Production deployment failed health check"
print_status "Rolling back..."
rollback_deployment
exit 1
fi
}
update_deployment() {
print_header "Updating Production Deployment"
# Build new images
build_production_images
# Rolling update
print_status "Performing rolling update..."
# Update app service
docker-compose -f docker-compose.prod.yml up -d --no-deps app
# Wait and health check
sleep 20
if check_production_health; then
print_success "Update completed successfully"
else
print_error "Update failed, rolling back..."
rollback_deployment
exit 1
fi
}
rollback_deployment() {
print_header "Rolling Back Deployment"
# Get previous version
local previous_version=$(docker images misinformation-heatmap --format "table {{.Tag}}" | grep -v latest | head -n 2 | tail -n 1)
if [[ -n "$previous_version" ]]; then
print_status "Rolling back to version: $previous_version"
# Update with previous version
export VERSION=$previous_version
docker-compose -f docker-compose.prod.yml up -d --no-deps app
sleep 20
if check_production_health; then
print_success "Rollback completed successfully"
else
print_error "Rollback failed"
exit 1
fi
else
print_error "No previous version found for rollback"
exit 1
fi
}
stop_production() {
print_header "Stopping Production Environment"
print_warning "This will stop the production environment. Are you sure? (y/N)"
read -r confirmation
if [[ "$confirmation" =~ ^[Yy]$ ]]; then
docker-compose -f docker-compose.prod.yml down
print_success "Production environment stopped"
else
print_status "Operation cancelled"
fi
}
show_production_logs() {
local service=${1:-}
if [[ -n "$service" ]]; then
print_header "Showing Production Logs for $service"
docker-compose -f docker-compose.prod.yml logs -f --tail=100 "$service"
else
print_header "Showing Production Logs for All Services"
docker-compose -f docker-compose.prod.yml logs -f --tail=100
fi
}
show_production_status() {
print_header "Production Service Status"
docker-compose -f docker-compose.prod.yml ps
echo ""
print_status "Resource usage:"
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
echo ""
print_status "Disk usage:"
df -h
}
check_production_health() {
print_status "Checking production health..."
local health_ok=true
# Check main application
if curl -k -s https://localhost/health > /dev/null; then
print_success "Application is healthy"
else
print_error "Application health check failed"
health_ok=false
fi
# Check Redis
if docker-compose -f docker-compose.prod.yml exec -T redis redis-cli ping | grep -q PONG; then
print_success "Redis is healthy"
else
print_error "Redis health check failed"
health_ok=false
fi
# Check Prometheus
if curl -s http://localhost:9090/-/healthy > /dev/null; then
print_success "Prometheus is healthy"
else
print_warning "Prometheus health check failed"
fi
# Check Grafana
if curl -s http://localhost:3001/api/health > /dev/null; then
print_success "Grafana is healthy"
else
print_warning "Grafana health check failed"
fi
$health_ok
}
backup_production_data() {
print_header "Creating Production Data Backup"
local backup_date=$(date +%Y%m%d_%H%M%S)
local backup_dir="backups/backup_$backup_date"
mkdir -p "$backup_dir"
# Backup application data
print_status "Backing up application data..."
docker run --rm -v misinformation-heatmap_app-data:/data -v $(pwd)/$backup_dir:/backup alpine tar czf /backup/app-data.tar.gz -C /data .
# Backup Redis data
print_status "Backing up Redis data..."
docker-compose -f docker-compose.prod.yml exec -T redis redis-cli BGSAVE
sleep 5
docker run --rm -v misinformation-heatmap_redis-prod-data:/data -v $(pwd)/$backup_dir:/backup alpine tar czf /backup/redis-data.tar.gz -C /data .
# Backup Grafana data
print_status "Backing up Grafana data..."
docker run --rm -v misinformation-heatmap_grafana-prod-data:/data -v $(pwd)/$backup_dir:/backup alpine tar czf /backup/grafana-data.tar.gz -C /data .
# Create backup manifest
cat > "$backup_dir/manifest.txt" << EOF
Backup created: $(date)
Version: ${VERSION:-unknown}
Services backed up:
- Application data
- Redis data
- Grafana data
EOF
print_success "Backup created: $backup_dir"
}
restore_production_data() {
local backup_dir=${1:-}
if [[ -z "$backup_dir" ]]; then
print_error "Please specify backup directory"
print_status "Available backups:"
ls -la backups/ 2>/dev/null || print_status "No backups found"
exit 1
fi
if [[ ! -d "$backup_dir" ]]; then
print_error "Backup directory not found: $backup_dir"
exit 1
fi
print_header "Restoring Production Data from $backup_dir"
print_warning "This will overwrite current production data. Are you sure? (y/N)"
read -r confirmation
if [[ "$confirmation" =~ ^[Yy]$ ]]; then
# Stop services
print_status "Stopping services..."
docker-compose -f docker-compose.prod.yml stop app redis grafana
# Restore data
print_status "Restoring application data..."
docker run --rm -v misinformation-heatmap_app-data:/data -v $(pwd)/$backup_dir:/backup alpine tar xzf /backup/app-data.tar.gz -C /data
print_status "Restoring Redis data..."
docker run --rm -v misinformation-heatmap_redis-prod-data:/data -v $(pwd)/$backup_dir:/backup alpine tar xzf /backup/redis-data.tar.gz -C /data
print_status "Restoring Grafana data..."
docker run --rm -v misinformation-heatmap_grafana-prod-data:/data -v $(pwd)/$backup_dir:/backup alpine tar xzf /backup/grafana-data.tar.gz -C /data
# Restart services
print_status "Restarting services..."
docker-compose -f docker-compose.prod.yml start app redis grafana
print_success "Data restoration completed"
else
print_status "Operation cancelled"
fi
}
scale_services() {
local scale_config=${1:-}
if [[ -z "$scale_config" ]]; then
print_error "Please specify scaling configuration (e.g., app=3)"
exit 1
fi
print_header "Scaling Production Services"
print_status "Scaling: $scale_config"
docker-compose -f docker-compose.prod.yml up -d --scale "$scale_config"
print_success "Scaling completed"
show_production_status
}
clean_production_resources() {
print_header "Cleaning Production Resources"
print_warning "This will remove unused images and containers. Continue? (y/N)"
read -r confirmation
if [[ "$confirmation" =~ ^[Yy]$ ]]; then
print_status "Removing unused images..."
docker image prune -f
print_status "Removing old versions (keeping last 3)..."
docker images misinformation-heatmap --format "table {{.Tag}}" | grep -v latest | tail -n +4 | xargs -r docker rmi misinformation-heatmap: 2>/dev/null || true
print_status "Removing unused volumes..."
docker volume prune -f
print_success "Cleanup completed"
else
print_status "Operation cancelled"
fi
}
main() {
case "${1:-}" in
build)
check_prerequisites
build_production_images
;;
deploy)
check_prerequisites
deploy_production
;;
update)
check_prerequisites
update_deployment
;;
rollback)
rollback_deployment
;;
stop)
stop_production
;;
logs)
show_production_logs "${2:-}"
;;
status)
show_production_status
;;
health)
check_production_health
;;
backup)
backup_production_data
;;
restore)
restore_production_data "${2:-}"
;;
scale)
scale_services "${2:-}"
;;
clean)
clean_production_resources
;;
-h|--help|help)
show_usage
;;
"")
print_error "No command specified"
show_usage
exit 1
;;
*)
print_error "Unknown command: $1"
show_usage
exit 1
;;
esac
}
main "$@" |