# MotoVaultPro GitLab CI/CD Pipeline # GitLab 18.6+ with shell executor # See docs/CICD-DEPLOY.md for complete documentation stages: - validate - build - deploy - verify variables: DOCKER_COMPOSE_FILE: docker-compose.yml DOCKER_COMPOSE_PROD_FILE: docker-compose.prod.yml # ------------------------------------------------------------------------------ # Validate Stage - Check prerequisites # ------------------------------------------------------------------------------ validate: stage: validate only: - main script: - echo "==========================================" - echo "Validating deployment prerequisites..." - echo "==========================================" - echo "Checking Docker..." - docker info > /dev/null 2>&1 || (echo "ERROR: Docker not accessible" && exit 1) - echo "OK: Docker is accessible" - echo "Checking Docker Compose..." - docker compose version > /dev/null 2>&1 || (echo "ERROR: Docker Compose not available" && exit 1) - echo "OK: Docker Compose is available" - echo "Checking deployment path..." - test -d "$DEPLOY_PATH" || (echo "ERROR: DEPLOY_PATH ($DEPLOY_PATH) not found" && exit 1) - echo "OK: Deployment path exists" - echo "==========================================" - echo "Validation complete" - echo "==========================================" # ------------------------------------------------------------------------------ # Build Stage - Build Docker images # ------------------------------------------------------------------------------ build: stage: build only: - main script: - echo "==========================================" - echo "Building Docker images..." - echo "==========================================" - cd "$DEPLOY_PATH" - echo "Pulling latest code..." - git fetch origin main - git reset --hard origin/main - echo "Building images..." - docker compose -f $DOCKER_COMPOSE_FILE build --no-cache - echo "==========================================" - echo "Build complete" - echo "==========================================" # ------------------------------------------------------------------------------ # Deploy Stage - Inject secrets and deploy services # ------------------------------------------------------------------------------ deploy: stage: deploy only: - main environment: name: production url: https://motovaultpro.com script: - echo "==========================================" - echo "Deploying MotoVaultPro..." - echo "==========================================" - cd "$DEPLOY_PATH" # Inject secrets from GitLab File variables - echo "Step 1/6: Injecting secrets..." - chmod +x scripts/inject-secrets.sh - ./scripts/inject-secrets.sh # Stop existing services gracefully - echo "Step 2/6: Stopping existing services..." - docker compose -f $DOCKER_COMPOSE_FILE -f $DOCKER_COMPOSE_PROD_FILE down --timeout 30 || true # Pull latest base images - echo "Step 3/6: Pulling base images..." - docker compose -f $DOCKER_COMPOSE_FILE pull # Start database services first for migrations - echo "Step 4/6: Starting database services..." - docker compose -f $DOCKER_COMPOSE_FILE -f $DOCKER_COMPOSE_PROD_FILE up -d mvp-postgres mvp-redis - echo "Waiting for database to be ready..." - sleep 15 # Run database migrations - echo "Step 5/6: Running database migrations..." - docker compose -f $DOCKER_COMPOSE_FILE run --rm mvp-backend npm run migrate || echo "Migration command not found or no migrations to run" # Start all services - echo "Step 6/6: Starting all services..." - docker compose -f $DOCKER_COMPOSE_FILE -f $DOCKER_COMPOSE_PROD_FILE up -d # Wait for services to start - echo "Waiting for services to initialize..." - sleep 30 - echo "==========================================" - echo "Deployment complete" - echo "==========================================" # ------------------------------------------------------------------------------ # Verify Stage - Health checks # ------------------------------------------------------------------------------ verify: stage: verify only: - main script: - echo "==========================================" - echo "Verifying deployment..." - echo "==========================================" - cd "$DEPLOY_PATH" # Check all containers are running - echo "Checking container status..." - | FAILED=0 for service in mvp-traefik mvp-frontend mvp-backend mvp-postgres mvp-redis; do status=$(docker inspect --format='{{.State.Status}}' $service 2>/dev/null || echo "not found") if [ "$status" != "running" ]; then echo "ERROR: $service is not running (status: $status)" docker logs $service --tail 50 2>/dev/null || true FAILED=1 else echo "OK: $service is running" fi done if [ $FAILED -eq 1 ]; then echo "One or more services failed to start" exit 1 fi # Check backend health endpoint - echo "Checking backend health..." - | HEALTH_OK=0 for i in 1 2 3 4 5 6; do if curl -sf http://localhost:3001/health > /dev/null 2>&1; then echo "OK: Backend health check passed" HEALTH_OK=1 break fi echo "Attempt $i/6: Backend not ready, waiting 10s..." sleep 10 done if [ $HEALTH_OK -eq 0 ]; then echo "ERROR: Backend health check failed after 6 attempts" docker logs mvp-backend --tail 100 exit 1 fi # Check frontend is accessible - echo "Checking frontend..." - | if curl -sf http://localhost:3000 > /dev/null 2>&1; then echo "OK: Frontend is accessible" else echo "WARNING: Frontend check failed (might need Traefik routing)" fi - echo "==========================================" - echo "Deployment verified successfully!" - echo "==========================================" - echo "Application URL: https://motovaultpro.com"