Files
michaelschiemer/deployment/scripts/deploy.sh
Michael Schiemer 5e74ce73a6
All checks were successful
Test Runner / test-basic (push) Successful in 9s
Test Runner / test-php (push) Successful in 8s
Deploy Application / deploy (push) Successful in 43s
fix(deploy): force remove containers before deployment
The --force-recreate flag alone doesn't handle containers that exist
outside the compose project context. Now explicitly:
1. Run docker compose down first
2. Force remove any orphaned containers with known names
3. Then create fresh containers
2025-11-24 22:10:38 +01:00

189 lines
5.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ==============================================================================
# Application Deployment Script
# ==============================================================================
# Deploys application to staging or production environment
# Usage: ./deploy.sh <environment> [options]
# ==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${BLUE}${NC} $1"
}
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}⚠️${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
# Parse arguments
ENVIRONMENT=$1
BUILD_IMAGES=${2:-false}
if [ -z "$ENVIRONMENT" ]; then
print_error "Usage: $0 <environment> [build]"
print_info "Environments: staging, production"
print_info "Options: build - Build Docker images before deployment"
exit 1
fi
if [ "$ENVIRONMENT" != "staging" ] && [ "$ENVIRONMENT" != "production" ]; then
print_error "Invalid environment: $ENVIRONMENT"
print_info "Valid environments: staging, production"
exit 1
fi
# Set compose files
COMPOSE_BASE="docker-compose.base.yml"
if [ "$ENVIRONMENT" = "staging" ]; then
COMPOSE_ENV="docker-compose.staging.yml"
elif [ "$ENVIRONMENT" = "production" ]; then
COMPOSE_ENV="docker-compose.prod.yml"
fi
COMPOSE_FILES="-f $COMPOSE_BASE -f $COMPOSE_ENV"
print_info "Deploying to $ENVIRONMENT environment..."
# Check if secrets exist
SECRETS_DIR="deployment/secrets/$ENVIRONMENT"
if [ ! -d "$SECRETS_DIR" ]; then
print_warning "Secrets directory not found: $SECRETS_DIR"
print_info "Creating secrets directory..."
mkdir -p "$SECRETS_DIR"
fi
MISSING_SECRETS=()
REQUIRED_SECRETS=("db_password.txt" "redis_password.txt" "app_key.txt")
for secret_file in "${REQUIRED_SECRETS[@]}"; do
if [ ! -f "$SECRETS_DIR/$secret_file" ]; then
MISSING_SECRETS+=("$secret_file")
fi
done
if [ ${#MISSING_SECRETS[@]} -gt 0 ]; then
print_error "Missing required secrets:"
for secret in "${MISSING_SECRETS[@]}"; do
print_error " - $SECRETS_DIR/$secret"
done
print_info "See deployment/infrastructure/SECRETS.md for instructions"
exit 1
fi
# Check if infrastructure networks exist
print_info "Checking infrastructure networks..."
if ! docker network ls | grep -q "traefik-public"; then
print_error "traefik-public network not found"
print_info "Please deploy infrastructure stacks first:"
print_info " cd deployment/infrastructure && ./deploy.sh traefik"
exit 1
fi
if ! docker network ls | grep -q "app-internal"; then
print_error "app-internal network not found"
print_info "Please deploy infrastructure stacks first:"
print_info " cd deployment/infrastructure && ./deploy.sh postgresql"
exit 1
fi
# Build images if requested
if [ "$BUILD_IMAGES" = "build" ]; then
print_info "Building Docker images..."
docker compose $COMPOSE_FILES build
fi
# Pull latest images
print_info "Pulling latest images..."
docker compose $COMPOSE_FILES pull || print_warning "Failed to pull some images, continuing..."
# Stop and remove existing containers to prevent name conflicts
print_info "Stopping existing containers..."
docker compose $COMPOSE_FILES down --remove-orphans || print_warning "No existing containers to stop"
# Remove any orphaned containers with conflicting names
for container in nginx php redis scheduler queue-worker; do
if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
print_warning "Removing orphaned container: $container"
docker rm -f "$container" 2>/dev/null || true
fi
done
# Deploy stack
print_info "Deploying application stack..."
docker compose $COMPOSE_FILES up -d --force-recreate --remove-orphans
# Wait for services to be healthy
print_info "Waiting for services to be healthy..."
sleep 10
# Check service status
print_info "Checking service status..."
docker compose $COMPOSE_FILES ps
# Health checks
print_info "Running health checks..."
HEALTH_CHECK_FAILED=0
# Check PHP service
if docker compose $COMPOSE_FILES exec -T php php -v > /dev/null 2>&1; then
print_success "PHP service is healthy"
else
print_error "PHP service health check failed"
HEALTH_CHECK_FAILED=1
fi
# Check Redis service
if docker compose $COMPOSE_FILES exec -T redis redis-cli ping > /dev/null 2>&1; then
print_success "Redis service is healthy"
else
print_error "Redis service health check failed"
HEALTH_CHECK_FAILED=1
fi
# Check Nginx service
if docker compose $COMPOSE_FILES exec -T nginx wget --quiet --tries=1 --spider http://localhost/health > /dev/null 2>&1; then
print_success "Nginx service is healthy"
else
print_warning "Nginx health check endpoint not available (this may be normal)"
fi
if [ $HEALTH_CHECK_FAILED -eq 1 ]; then
print_error "Some health checks failed. Check logs:"
print_info " docker compose $COMPOSE_FILES logs"
exit 1
fi
print_success "Deployment to $ENVIRONMENT completed successfully!"
# Show service URLs
if [ "$ENVIRONMENT" = "production" ]; then
print_info "Application URL: https://michaelschiemer.de"
elif [ "$ENVIRONMENT" = "staging" ]; then
print_info "Application URL: https://staging.michaelschiemer.de"
fi
print_info "View logs: docker compose $COMPOSE_FILES logs -f"
print_info "View status: docker compose $COMPOSE_FILES ps"