3.6 KiB
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) |