Files
michaelschiemer/deployment/docs/guides/initial-deployment-guide.md
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

7.3 KiB

Initial Deployment Guide

Stand: 2025-11-07
Status: Vollständige Anleitung für erstes Deployment


Übersicht

Dieser Guide führt durch das komplette Initial Deployment des Application Stacks. Dieser Prozess wird einmalig beim ersten Setup durchgeführt. Für spätere Deployments siehe Code Deployment Workflow.

📖 Verwandte Dokumentation:


Voraussetzungen

Bevor das Initial Deployment startet, müssen folgende Voraussetzungen erfüllt sein:

1. Infrastructure Stacks deployed

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/setup-infrastructure.yml \
  --vault-password-file secrets/.vault_pass \
  --skip-tags application

Wichtig: --skip-tags application überspringt den Application Stack, da dieser separat deployed wird.

2. Docker Image gebaut und gepusht

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/build-initial-image.yml \
  --vault-password-file secrets/.vault_pass

Was passiert:

  • docker/entrypoint.sh wird auf LF Line Endings konvertiert (CRLF → LF)
  • Docker Image wird gebaut (Dockerfile.production)
  • Image wird zur Registry gepusht (localhost:5000/framework:latest)

3. Secrets konfiguriert

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/setup-production-secrets.yml \
  --vault-password-file secrets/.vault_pass

Erforderliche Secrets im Vault:

  • vault_db_user_password - PostgreSQL Passwort
  • vault_redis_password - Redis Passwort
  • vault_app_key - Application Encryption Key
  • vault_vault_encryption_key - Vault Encryption Key

Initial Deployment Workflow

Schritt 1: Application Code synchronisieren

Methode: Rsync-basiertes Sync vom lokalen Repository zum Server

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/sync-application-code.yml \
  --vault-password-file secrets/.vault_pass

Was passiert:

  • Zielverzeichnis wird erstellt: /home/deploy/michaelschiemer/current
  • Alte Dateien werden gelöscht (.git wird erhalten falls vorhanden)
  • Code wird via rsync synchronisiert
  • Excludes: vendor, node_modules, .env, deployment, docker, docs, tests
  • Executable Permissions werden auf worker.php und console.php gesetzt
  • Verifikation: Prüft ob worker.php, console.php, composer.json existieren

Wichtig: vendor wird nicht synchronisiert, da Dependencies im Container installiert werden.

Schritt 2: Composer Dependencies installieren

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/install-composer-dependencies.yml \
  --vault-password-file secrets/.vault_pass

Was passiert:

  • composer install --no-dev --optimize-autoloader wird im php Container ausgeführt
  • vendor/autoload.php wird erstellt
  • queue-worker und scheduler werden neu gestartet (um vendor zu erkennen)

Voraussetzung: php Container muss bereits laufen (wird durch setup-infrastructure.yml gestartet).

Schritt 3: Application Stack deployen

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/setup-infrastructure.yml \
  --vault-password-file secrets/.vault_pass \
  --tags application

Was passiert:

  • Docker Compose Stack wird deployed
  • Secrets werden erstellt
  • .env Datei wird generiert
  • Container werden gestartet: php, web, queue-worker, scheduler
  • Health Checks werden durchgeführt

Container-Konfiguration:

  • php: Läuft PHP-FPM und Nginx (via entrypoint.sh)
  • web: Nginx Reverse Proxy
  • queue-worker: PHP CLI Worker (ohne entrypoint, direkter php worker.php Aufruf)
  • scheduler: PHP CLI Scheduler (ohne entrypoint, direkter php console.php scheduler:run Aufruf)

Verifikation

Container Status prüfen

cd deployment/ansible
ansible-playbook -i inventory/production.yml \
  playbooks/check-final-status.yml \
  --vault-password-file secrets/.vault_pass

Erwartetes Ergebnis:

NAME                          STATUS
production-php-1             Up X minutes (healthy)
production-web-1              Up X minutes (healthy)
production-queue-worker-1     Up X minutes
scheduler                     Up X minutes

Manuelle Verifikation

# SSH zum Server
ssh deploy@94.16.110.151

# Container Status
cd ~/deployment/stacks/production
docker compose -f docker-compose.base.yml -f docker-compose.production.yml ps

# Logs prüfen
docker compose -f docker-compose.base.yml -f docker-compose.production.yml logs web
docker compose -f docker-compose.base.yml -f docker-compose.production.yml logs queue-worker
docker compose -f docker-compose.base.yml -f docker-compose.production.yml logs scheduler

# Health Check
curl -k https://localhost/health

Häufige Probleme

Problem: Container starten nicht / sind unhealthy

Lösung: Siehe Troubleshooting Guide

Häufige Ursachen:

  • Missing Secret Files → setup-production-secrets.yml ausführen
  • Missing Application Code → sync-application-code.yml ausführen
  • Missing vendor/autoload.phpinstall-composer-dependencies.yml ausführen
  • PHP-FPM Permission Errors → fix-web-container.yml ausführen
  • Environment Variables fehlen → recreate-containers-with-env.yml ausführen

Problem: Entrypoint Script "no such file or directory"

Ursache: CRLF Line Endings im docker/entrypoint.sh

Lösung:

  • .gitattributes sollte *.sh text eol=lf enthalten
  • build-initial-image.yml konvertiert automatisch zu LF

Problem: worker.php oder console.php fehlen

Ursache: Code wurde nicht synchronisiert

Lösung: sync-application-code.yml erneut ausführen


Unterschiede: Initial vs. Normal Deployment

Initial Deployment (dieser Guide)

  • Code-Sync: Rsync vom lokalen Repository
  • Verwendung: Einmalig beim ersten Setup
  • Playbook: sync-application-code.yml

Normal Deployment (CI/CD)

  • Code-Sync: Git Clone/Pull auf dem Server
  • Verwendung: Regelmäßige Deployments via CI/CD
  • Playbook: deploy-application-code.yml

Siehe auch: Code Deployment Workflow


Nächste Schritte

Nach erfolgreichem Initial Deployment:

  1. CI/CD Pipeline konfigurieren

    • Gitea Actions Workflow einrichten
    • deploy-application-code.yml für zukünftige Deployments verwenden
  2. Monitoring einrichten

    • Health Checks verifizieren
    • Logs überwachen
    • Alerts konfigurieren
  3. Backup-Strategie

    • Database Backups einrichten
    • Application Data Backups konfigurieren

Referenz