Files
michaelschiemer/deployment/README.md

6.3 KiB

Pragmatic Production Deployment Setup

Architecture Overview

This deployment setup uses separate Docker Compose stacks for better maintainability and clear separation of concerns.

Infrastructure Components

Production Server (94.16.110.151)
├── Stack 1: Traefik (Reverse Proxy & SSL)
├── Stack 2: Gitea (Git Server + MySQL + Redis)
├── Stack 3: Docker Registry (Private Registry)
├── Stack 4: Application (PHP + Nginx + Redis + Queue Workers)
├── Stack 5: PostgreSQL (Database)
└── Stack 6: Monitoring (Portainer + Grafana + Prometheus)

Development Machine
└── Gitea Actions Runner (local, Docker-in-Docker)

Deployment Flow

Developer → git push
         ↓
    Gitea (Production)
         ↓
    Gitea Actions (Dev Machine)
         ↓
    Build Docker Image
         ↓
    Push to Private Registry
         ↓
    SSH/Ansible → Production Server
         ↓
    docker compose pull
         ↓
    docker compose up -d

Directory Structure

deployment/
├── stacks/                    # Docker Compose stacks
│   ├── traefik/              # Reverse proxy with SSL
│   ├── gitea/                # Git server
│   ├── registry/             # Private Docker registry
│   ├── application/          # Main PHP application
│   ├── postgres/             # Database
│   └── monitoring/           # Portainer + Grafana + Prometheus
├── ansible/                   # Automation playbooks
│   ├── playbooks/            # Deployment automation
│   ├── inventory/            # Server inventory
│   └── secrets/              # Ansible Vault secrets
├── runner/                    # Gitea Actions runner (dev machine)
├── scripts/                   # Helper scripts
└── docs/                      # Deployment documentation

Getting Started

Prerequisites

Production Server:

  • Docker & Docker Compose installed
  • Firewall configured (ports 80, 443, 2222)
  • User deploy with Docker permissions
  • SSH access configured

Development Machine:

  • Docker & Docker Compose installed
  • Ansible installed
  • SSH key configured for production server

Initial Setup

  1. Deploy Infrastructure Stacks (Production)

    cd deployment/stacks/traefik && docker compose up -d
    cd ../postgres && docker compose up -d
    cd ../registry && docker compose up -d
    cd ../gitea && docker compose up -d
    cd ../monitoring && docker compose up -d
    
  2. Setup Gitea Runner (Development)

    cd deployment/runner
    docker compose up -d
    
  3. Deploy Application

    cd deployment/ansible
    ansible-playbook -i inventory/production.yml playbooks/deploy-application.yml
    

Stack Documentation

Each stack has its own README with detailed configuration:

Deployment Commands

Manual Deployment

./scripts/deploy.sh

Rollback to Previous Version

./scripts/rollback.sh

Update Specific Stack

cd stacks/<stack-name>
docker compose pull
docker compose up -d

CI/CD Pipeline

The CI/CD pipeline is defined in .gitea/workflows/production-deploy.yml and runs automatically on push to main branch.

Quick Start: Deploy Code Changes

# 1. Make changes locally
# ... edit files ...

# 2. Commit changes
git add .
git commit -m "feat: Add new feature"

# 3. Push to main → Automatic deployment starts
git push origin main

What happens automatically:

  • Tests run (~2-5 min)
  • Docker image is built (~3-5 min)
  • Image is pushed to registry (~1-2 min)
  • Ansible deployment runs (~2-4 min)
  • Application stack is updated

Total time: ~8-15 minutes

Status check:

  • Pipeline status: https://git.michaelschiemer.de/michael/michaelschiemer/actions
  • Application status: ssh deploy@94.16.110.151 "cd ~/deployment/stacks/application && docker compose ps"

📖 Detailed Documentation:

Pipeline Details

The CI/CD pipeline runs on push to main branch:

  1. Build Stage: Build Docker image
  2. Push Stage: Push to private registry
  3. Deploy Stage: Deploy to production via Ansible

Monitoring

Access monitoring tools:

Backup & Recovery

Automated Backups

  • PostgreSQL: Daily backups with 7-day retention
  • Gitea Data: Weekly backups
  • Registry Images: On-demand backups

Manual Backup

ansible-playbook -i inventory/production.yml playbooks/backup.yml

Restore from Backup

ansible-playbook -i inventory/production.yml playbooks/restore.yml

Security

  • All external services behind Traefik with HTTPS
  • Private registry with BasicAuth
  • Secrets managed via Ansible Vault
  • Regular security updates via Watchtower

Troubleshooting

Check Stack Health

cd stacks/<stack-name>
docker compose ps
docker compose logs -f

Check Service Connectivity

curl -I https://app.yourdomain.com
docker network inspect traefik-public

View Logs

# Application logs
docker compose -f stacks/application/docker-compose.yml logs -f app-php

# Traefik logs
docker compose -f stacks/traefik/docker-compose.yml logs -f

Support

For issues and questions, see:

Migration from Docker Swarm

See Migration Guide for detailed instructions on migrating from the old Docker Swarm setup.

License

This deployment configuration is part of the Custom PHP Framework project.