# 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. **DNS Configuration**: `staging.michaelschiemer.de` points to server IP
3. **Docker Networks**:
   ```bash
   docker network create traefik-public  # Shared with production
   docker network create staging-internal  # Staging-only
   ```

## Configuration

### 1. Create Environment File

```bash
cp .env.example .env
```

### 2. Configure Environment Variables

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

# Database (can use separate staging DB or share)
DB_DATABASE=michaelschiemer_staging
DB_HOST=postgres
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`.

```bash
# 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

```bash
# 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 | michaelschiemer_staging |
| **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 `staging` → `main` → deploy to production

## Troubleshooting

### Staging not accessible

```bash
# 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

```bash
# 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:

```bash
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
```
