INBOX/checkpoint-deployment.md
2026-08-07 16:01:24 +02:00

3.6 KiB

CheckPoint Ehrenamt — Deployment & Betrieb

Flask/Gunicorn · Docker · cpe.bujour.info · Stand: Juni 2026


Überblick

CheckPoint Ehrenamt läuft als Docker-Container auf dem EU-VPS hinter Caddy. Das Image wird direkt auf dem VPS aus dem geklonten Forgejo-Repo gebaut — kein Container-Registry, kein CI/CD.

URL: https://cpe.bujour.info Repo: https://git.bujour.de/patsy/CP_EHRENAMT Code auf VPS: ~/apps/checkpoint/ Stack: ~/stacks/checkpoint/


Stack-Struktur

~/stacks/checkpoint/
├── compose.yaml
└── .env          ← SECRET_KEY (nicht im Git)

~/apps/checkpoint/
├── Dockerfile
├── wsgi.py
├── gunicorn.conf.py
├── seed.py
├── requirements.txt
├── app/
└── instance/     ← DB + Uploads (Docker Volume)

compose.yaml

services:
  checkpoint:
    build: /home/patsy/apps/checkpoint
    container_name: checkpoint
    restart: unless-stopped
    environment:
      - CP_ENV=production
      - SECRET_KEY=${SECRET_KEY}
    volumes:
      - checkpoint_data:/app/instance
    networks:
      - proxy
    expose:
      - "8000"

volumes:
  checkpoint_data:

networks:
  proxy:
    external: true

Erstes Deployment (Einmalig)

# 1. Repo klonen
git clone ssh://git@git.bujour.de:2222/patsy/CP_EHRENAMT.git ~/apps/checkpoint

# 2. Secret generieren
python3 -c "import secrets; print('SECRET_KEY=' + secrets.token_urlsafe(48))" \
  > ~/stacks/checkpoint/.env

# 3. Image bauen und Container starten
cd ~/stacks/checkpoint
docker compose build
docker compose up -d

# 4. Datenbank seeden (einmalig)
docker exec checkpoint python seed.py

# 5. Ersten Admin anlegen (einmalig)
docker exec -e SECRET_KEY=$(grep SECRET_KEY ~/stacks/checkpoint/.env | cut -d= -f2) \
  checkpoint flask --app wsgi create-admin <nutzername> "<anzeigename>" "<passwort>"

Update einspielen

cd ~/apps/checkpoint
git pull

cd ~/stacks/checkpoint
docker compose build
docker compose up -d

Neue Tabellen werden beim Start automatisch via db.create_all() angelegt. Achtung: Bestehende Tabellen werden nicht migriert — bei Schema-Änderungen vorher Backup ziehen und ggf. manuell migrieren.


Weitere Admins anlegen

docker exec -e SECRET_KEY=$(grep SECRET_KEY ~/stacks/checkpoint/.env | cut -d= -f2) \
  checkpoint flask --app wsgi create-admin <nutzername> "<anzeigename>" "<passwort>"

Datenbank-Backup (manuell)

docker exec checkpoint sqlite3 /app/instance/checkpoint.sqlite \
  ".backup '/app/instance/checkpoint-backup-$(date +%Y%m%d).sqlite'"

Das Backup liegt im Volume unter /app/instance/ und kann von dort kopiert werden.


Logs

# Live-Logs
docker logs checkpoint -f

# Letzte 100 Zeilen
docker logs checkpoint --tail 100

Fehlersuche

Problem Ursache Lösung
500 nach Deploy Fehlendes SECRET_KEY .env prüfen, Container neu starten
Login funktioniert nicht CP_ENV nicht gesetzt docker exec checkpoint env | grep CP_ENV
App nicht erreichbar Caddy oder Container down docker ps, dann Caddy-Reload
„database is locked" Zu viele Worker für SQLite workers in gunicorn.conf.py auf 2 senken

Technischer Stack

Komponente Entscheidung
Backend Python 3.13 + Flask
WSGI gunicorn (3 Worker, gthread)
Datenbank SQLite mit WAL-Modus
Templating Jinja2, server-rendered
CSS Selbst gebaut, kein Framework
JavaScript Minimal, Vanilla (nur Chat-Polling + Sidebar)
CSRF Selbst gebaut (Session-Token, kein Flask-WTF)
Hosting IONOS EU-VPS, Docker, Caddy (TLS automatisch)