Some checks failed
Deploy Application / deploy (push) Has been cancelled
177 lines
5.0 KiB
Bash
Executable File
177 lines
5.0 KiB
Bash
Executable File
#!/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..."
|
||
|
||
# Deploy stack
|
||
print_info "Deploying application stack..."
|
||
docker compose $COMPOSE_FILES up -d
|
||
|
||
# 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"
|
||
|