#!/bin/bash # Direct Docker-based production deployment # Bypasses Ansible for immediate deployment set -euo pipefail SERVER_USER="deploy" SERVER_IP="94.16.110.151" REMOTE_PATH="/home/deploy/michaelschiemer" SSH_OPTS="-o StrictHostKeyChecking=no" # Colors for output GREEN="\e[32m" YELLOW="\e[33m" RED="\e[31m" RESET="\e[0m" log_info() { echo -e "${YELLOW}[INFO]${RESET} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${RESET} $1" } log_error() { echo -e "${RED}[ERROR]${RESET} $1" } # Check prerequisites check_prerequisites() { log_info "Checking prerequisites..." if ! ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "echo 'SSH connection successful'" 2>/dev/null; then log_error "Cannot connect to production server. Please configure SSH key authentication." log_error "Run: ssh-copy-id -i ~/.ssh/production $SERVER_USER@$SERVER_IP" exit 1 fi if ! command -v docker &> /dev/null; then log_error "Docker not found locally. Install Docker first." exit 1 fi log_success "Prerequisites check passed" } # Build and push production image build_and_push() { local image_tag="$(git rev-parse --short HEAD)" log_info "Building production image with tag: $image_tag" # Build production image docker build -t "michaelschiemer/php-framework:$image_tag" \ -f docker/php/Dockerfile \ --target=production \ --build-arg ENV=production \ . # Tag as latest for production docker tag "michaelschiemer/php-framework:$image_tag" \ "michaelschiemer/php-framework:production" log_success "Production image built successfully" echo "$image_tag" } # Deploy to production server deploy_to_server() { local image_tag="$1" log_info "Deploying to production server..." # Create deployment directory ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "mkdir -p $REMOTE_PATH" # Copy docker-compose files scp $SSH_OPTS docker-compose.yml "$SERVER_USER@$SERVER_IP:$REMOTE_PATH/" scp $SSH_OPTS deployment/applications/docker-compose.production.yml "$SERVER_USER@$SERVER_IP:$REMOTE_PATH/" # Copy environment file template scp $SSH_OPTS .env.production "$SERVER_USER@$SERVER_IP:$REMOTE_PATH/.env" 2>/dev/null || { log_info "Creating production environment file..." ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "cat > $REMOTE_PATH/.env << 'EOF' APP_ENV=production APP_DEBUG=false DB_HOST=db DB_DATABASE=framework DB_USERNAME=framework DB_PASSWORD=secure_password_change_me REDIS_HOST=redis REDIS_PORT=6379 EOF" } # Save Docker image and transfer log_info "Transferring Docker image..." docker save "michaelschiemer/php-framework:$image_tag" | \ ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" "docker load" # Deploy with Docker Compose ssh $SSH_OPTS "$SERVER_USER@$SERVER_IP" " cd $REMOTE_PATH # Stop existing services docker compose -f docker-compose.yml -f docker-compose.production.yml down --remove-orphans || true # Start services with production configuration IMAGE_TAG=$image_tag docker compose -f docker-compose.yml -f docker-compose.production.yml up -d # Wait for services to be healthy sleep 30 # Run health check if docker compose -f docker-compose.yml -f docker-compose.production.yml ps | grep -q 'healthy\\|Up'; then echo 'Deployment successful!' else echo 'Health check failed!' docker compose -f docker-compose.yml -f docker-compose.production.yml logs --tail=50 exit 1 fi " log_success "Deployment completed successfully!" } # Validate deployment validate_deployment() { log_info "Validating production deployment..." # Test HTTPS endpoint if curl -f -k -H "User-Agent: Mozilla/5.0" "https://$SERVER_IP/health" >/dev/null 2>&1; then log_success "HTTPS health check passed" else log_error "HTTPS health check failed" return 1 fi # Check that debug routes are blocked local debug_response=$(curl -s -o /dev/null -w '%{http_code}' -k -H "User-Agent: Mozilla/5.0" "https://$SERVER_IP/debug" 2>/dev/null || echo 'connection_failed') if [ "$debug_response" = '404' ]; then log_success "Debug routes properly blocked" else log_error "WARNING: Debug routes not properly blocked (got: $debug_response)" fi log_success "Deployment validation completed" } # Main execution main() { log_info "Starting direct production deployment..." # Check prerequisites check_prerequisites # Build and get image tag local image_tag image_tag=$(build_and_push) # Deploy to server deploy_to_server "$image_tag" # Validate deployment validate_deployment log_success "Production deployment completed successfully!" log_info "Application available at: https://michaelschiemer.de" log_info "Deployed commit: $(git rev-parse HEAD)" } # Execute if run directly if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi