Files
michaelschiemer/deployment/stacks/staging
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00
..

Staging Stack - Staging Environment

Overview

Separate staging environment for testing features before production deployment.

URL: https://staging.michaelschiemer.de

Features:

  • Separate containers and volumes from production
  • Auto-deployment from staging branch
  • Shared Traefik network (same SSL certificates)
  • Separate Redis instance
  • Can use separate database or share with production

Services

  • staging-app (PHP-FPM) - Application runtime
  • staging-nginx (Nginx) - Web server for staging.michaelschiemer.de
  • staging-redis (Redis 7) - Separate cache/session/queue backend
  • staging-queue-worker - Background job processor
  • staging-scheduler - Cron job executor

Prerequisites

  1. Traefik Stack Running (shared with production)
  2. PostgreSQL Staging Stack Running (separate from production)
    cd ../postgresql-staging
    docker compose up -d
    
  3. DNS Configuration: staging.michaelschiemer.de points to server IP
  4. Docker Networks:
    docker network create traefik-public  # Shared with production
    docker network create staging-internal  # Staging-only
    docker network create postgres-staging-internal  # Staging database network
    

Configuration

1. Create Environment File

cp .env.example .env

2. Configure Environment Variables

# Staging-specific
APP_ENV=staging
APP_DEBUG=true
APP_URL=https://staging.michaelschiemer.de

# Database - using separate staging database stack
DB_DATABASE=michaelschiemer_staging
DB_HOST=postgres-staging
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=<password>

# Redis (separate instance)
# Note: REDIS_PASSWORD is loaded from Docker Secret via REDIS_PASSWORD_FILE
# See secrets/redis_password.txt file
CACHE_PREFIX=staging

# Git
GIT_REPOSITORY_URL=https://git.michaelschiemer.de/michael/michaelschiemer.git
GIT_BRANCH=staging
# Note: GIT_TOKEN is loaded from Docker Secret via GIT_TOKEN_FILE
# See secrets/git_token.txt file

Deployment

Initial Setup

The staging environment uses docker-compose.staging.yml in the repository root, which is used as an override for docker-compose.base.yml.

# Create staging stack directory on server
mkdir -p ~/deployment/stacks/staging

# Copy docker-compose files from repository
cp docker-compose.base.yml ~/deployment/stacks/staging/
cp docker-compose.staging.yml ~/deployment/stacks/staging/

# Create secrets directory and files
mkdir -p ~/deployment/stacks/staging/secrets
# Create secret files (redis_password.txt, db_user_password.txt, app_key.txt, etc.)
# These files should contain the actual secret values

# Ensure networks exist
docker network create traefik-public 2>/dev/null || true
docker network create staging-internal 2>/dev/null || true

# Start staging stack
cd ~/deployment/stacks/staging
docker compose -f docker-compose.base.yml -f docker-compose.staging.yml up -d

Auto-Deployment

Automatic: Push to staging branch triggers build, then auto-deploys to staging.

Manual: Use "Deploy to Staging" workflow in Gitea Actions.

Verify Deployment

# Check container status
cd ~/deployment/stacks/staging
docker compose -f docker-compose.base.yml -f docker-compose.staging.yml ps

# Test staging URL
curl https://staging.michaelschiemer.de/health

# View logs
docker compose logs -f staging-app
docker compose logs -f staging-nginx

Differences from Production

Aspect Production Staging
Domain michaelschiemer.de staging.michaelschiemer.de
Branch main staging
APP_ENV production staging
APP_DEBUG false true
Redis Separate instance Separate instance
Database michaelschiemer (postgres-production) michaelschiemer_staging (postgres-staging)
Database Stack postgresql-production (separate) postgresql-staging (separate)
Volumes app-* staging-*
Network app-internal staging-internal

Workflow

  1. Development: Feature branch → merge to staging
  2. Auto-Build: Push to staging triggers build-image.yml
  3. Auto-Deploy: Successful build auto-deploys to staging (via deploy-staging.yml)
  4. Testing: Test on https://staging.michaelschiemer.de
  5. Production: Merge stagingmain → deploy to production

Troubleshooting

Staging not accessible

# Check Traefik routing
docker logs traefik | grep staging

# Verify container is running
docker ps | grep staging

# Check nginx logs
docker logs staging-nginx

Code not updating

# Force code pull in staging-app
docker exec staging-app bash -c "cd /var/www/html && git pull origin staging"
cd ~/deployment/stacks/staging
docker compose -f docker-compose.base.yml -f docker-compose.staging.yml restart staging-app staging-nginx

Cleanup

To remove staging environment:

cd ~/deployment/stacks/staging
docker compose -f docker-compose.base.yml -f docker-compose.staging.yml down -v  # Removes volumes too
docker network rm staging-internal