Files
2026-08-03 13:38:11 +02:00

5.9 KiB

Deployment & CI/CD Guide

1. Docker Development Cycle

Der empfohlene Entwicklungs-Workflow nutzt Docker Compose für eine isolierte Umgebung mit Hot-Reload.

Voraussetzungen

  • Docker (v20.10+)
  • Docker Compose (v2.0+)

Ersts Start (Build & Initialize)

# Navigiere zum Projektverzeichnis
cd formeleon

# Build Images und Start Container
docker-compose up --build

Das Entrypoint-Script führt automatisch folgende Schritte aus:

  1. Prüft Python-Abhängigkeiten
  2. Führt Datenbank-Migrationen aus (flask db upgrade)
  3. Seeded die Datenbank mit Testdaten (flask seed-db) - nur bei leerer DB
  4. Startet den Flask-Entwicklungsserver mit Hot-Reload

Täglicher Entwicklungs-Workflow

Container starten/stoppen

# Starten (im Hintergrund)
docker-compose up -d

# Stoppen
docker-compose down

# Neu starten (nach Code-Änderungen)
docker-compose restart app

# Logs anzeigen
docker-compose logs -f app

Code-Änderungen testen

Dank der Volume-Mounts in docker-compose.yml werden Änderungen an folgenden Verzeichnissen sofort im Container sichtbar:

  • app.py, config.py, models.py
  • routes/
  • services/
  • utils/
  • templates/
  • static/
  • migrations/

Kein Container-Rebuild nötig! Der Flask-Dev-Server erkennt Änderungen und lädt neu.

Flask CLI-Kommandos in Docker

Führe Flask-Kommandos im laufenden Container aus:

# Allgemeine Syntax
docker-compose run --rm app flask <kommando>

# Beispiele:
# Migration erstellen
docker-compose run --rm app flask db migrate -m "add user table"

# Migration anwenden
docker-compose run --rm app flask db upgrade

# Migration zurücksetzen
docker-compose run --rm app flask db downgrade

# Datenbank mit Testdaten füllen
docker-compose run --rm app flask seed-db

# Mandanten verwalten
docker-compose run --rm app flask create-tenant "Test" "public-key-123"

# Benutzer verwalten
docker-compose run --rm app flask create-user "test@example.com" "Test User" --role=admin

Shell im Container

# Interaktive Shell
docker-compose exec app bash

# Python Shell
docker-compose exec app python

# Flask Shell (mit App-Kontext)
docker-compose exec app flask shell

Datenbank zurücksetzen

# Container stoppen und Volumes löschen (ACHTUNG: Alle Daten gehen verloren!)
docker-compose down -v

# Neu starten mit frischer Datenbank
docker-compose up --build

2. Docker Setup für Produktion

Für die Produktion sollte ein separates docker-compose.prod.yml erstellt werden.

docker-compose.prod.yml (Beispiel)

version: '3.8'

services:
  web:
    build: .
    container_name: formeleon-web
    ports:
      - "8000:5000"
    environment:
      - FLASK_ENV=production
      - FLASK_DEBUG=0
      - DEV_MODE=false
      - SECRET_KEY=${SECRET_KEY}
      - SQLALCHEMY_DATABASE_URI=${DATABASE_URL}
      - ZITADEL_ISSUER=${ZITADEL_ISSUER}
      - ZITADEL_CLIENT_ID=${ZITADEL_CLIENT_ID}
      - ZITADEL_CLIENT_SECRET=${ZITADEL_CLIENT_SECRET}
      - RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY}
      - RECAPTCHA_SECRET_KEY=${RECAPTCHA_SECRET_KEY}
    volumes:
      - ./data:/app/data
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/"]
      interval: 30s
      timeout: 10s
      retries: 3

  postgres:
    image: postgres:15-alpine
    container_name: formeleon-postgres
    environment:
      - POSTGRES_DB=formeleon
      - POSTGRES_USER=formeleon
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U formeleon"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

Produktion starten

# Mit kombinierter Konfiguration
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

# Logs anzeigen
docker-compose logs -f

# Status prüfen
docker-compose ps

3. Gitea Actions Workflow

Bei einem Push auf den main-Branch oder einem Release-Tag führt der Gitea-Runner automatisiert folgende Schritte auf dem Zielserver aus:

  1. Code-Update via git pull.
  2. Erstellen/Aktualisieren der Docker-Images.
  3. Zero-Downtime Restart der Container via Docker Compose.

Beispiel .gitea/workflows/deploy.yml

name: Deploy to Production
on:
  push:
    branches: [main]
    tags: ['v*']

jobs:
  deploy:
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Stop services
        run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml down
      
      - name: Pull latest images
        run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
      
      - name: Build and start
        run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
      
      - name: Run migrations
        run: docker-compose -f docker-compose.yml -f docker-compose.prod.yml run --rm web flask db upgrade
      
      - name: Cleanup
        run: docker system prune -f

4. Docker Troubleshooting

Häufige Probleme & Lösungen

Problem Lösung
Port 5000 bereits belegt docker-compose down und neu starten
Datenbank-Fehler docker-compose down -v && docker-compose up --build
Python-Module nicht gefunden docker-compose build --no-cache && docker-compose up
Container startet nicht docker-compose logs app prüfen
Hot-Reload funktioniert nicht Volume-Mounts in docker-compose.yml prüfen

Debug-Modus

# Container im Debug-Modus starten
docker-compose up --build --abort-on-container-exit

# Oder mit Shell
ENTERPOINT_OVERRIDE=bash docker-compose run --rm --service-ports app

Cache leeren

# Docker Cache leeren
docker builder prune

# Unused Images entfernen
docker image prune -a

# System cleanup
docker system prune -a --volumes