Setup (lokal)
Development-Stack auf der Workstation. Production (Server, Traefik, mTLS): Deployment. Compose-Kurzbefehle beider Welten: README im Projektroot.
Voraussetzungen
- Docker + Docker Compose
- Optional: Python 3 mit QGIS-Bindings (nur für
scripts/setup_qgis_forms.py) oder Docker-Imageqgis/qgis - QGIS 3.x / 4.x zum Testen der Formulare und der Karte
Konfiguration
cp .env.example .env
vim .env
Wichtige Variablen:
| Variable | Bedeutung |
|---|---|
POSTGRES_DB / POSTGRES_USER / POSTGRES_PASSWORD |
Superuser im Container |
POSTGRES_PORT |
Host-Port → Container 5432 (Default 3401, nur lokal/Dev) |
LINETRA_PG_HOST / LINETRA_PG_PORT |
Host/Port für QGIS: lokal localhost:3401; Server PgBouncer …:5432 |
POSTGRES_IMAGE |
Default postgis/postgis:17-3.5 |
REDIS_URL |
Broker (redis://redis:6379/0) |
FILE_STORAGE_DIR |
Rohinput / Exporte (/var/linetra/files, uid 1000 / appuser) |
LINETRA_PG_SSLMODE |
Lokal disable; Server/QGIS verify-full |
PGBOUNCER_PORT |
Host-Port des mTLS-Proxys (Default 5432) |
LINETRA_APP_USER / LINETRA_APP_PASSWORD |
Edit-Rolle für QGIS |
LINETRA_READONLY_USER / LINETRA_READONLY_PASSWORD |
Nur-Lesen-Rolle |
LINETRA_QGIS_USER |
User für Form-Setup-Skript |
.env nicht committen.
Zusätzliche Web-CMS-Variablen: SESSION_SECRET, CORS_ORIGINS, COOKIE_SECURE, DATABASE_HOST / DATABASE_PORT (Compose-intern postgres:5432), NEXT_PUBLIC_APP_URL, LOG_LEVEL (debug / info / warning / error / critical, Default info; DEBUG=true hebt auf debug), LOG_BUFFER_SIZE (50–5000, Default 500) für Settings → Log. info ist die grobe Normalstufe (Start/Stop, Login, …); HTTP-Access von Uvicorn erscheint erst bei debug und nur in den Container-Logs, nicht im Ringspeicher.
Gleiche Production-Datenbank
Die lokale FastAPI kann PostGIS auf dem NAS über PgBouncer mTLS nutzen (derselbe Weg wie QGIS). Production-FastAPI bleibt intern postgres:5432.
Auf dem Server (einmalig, CA liegt schon dort):
./scripts/pki/issue-client-cert.sh edit workstation
./scripts/pki/issue-client-cert.sh read workstation-read
Dateien auf die Workstation kopieren nach pgbouncer/certs/workstation/:
| Datei auf dem NAS | Datei lokal |
|---|---|
pgbouncer/certs/ca.crt |
ca.crt |
pgbouncer/certs/clients/workstation.crt + .key |
edit.crt / edit.key |
pgbouncer/certs/clients/workstation-read.crt + .key |
read.crt / read.key |
In der lokalen .env (nicht auf dem Server):
DATABASE_HOST=linetra.nasarek.dev
DATABASE_PORT=5432
DATABASE_SSLMODE=verify-full
DATABASE_SSLROOTCERT=/certs/ca.crt
DATABASE_SSLCERT_EDIT=/certs/edit.crt
DATABASE_SSLKEY_EDIT=/certs/edit.key
DATABASE_SSLCERT_READ=/certs/read.crt
DATABASE_SSLKEY_READ=/certs/read.key
LINETRA_APP_PASSWORD / LINETRA_READONLY_PASSWORD müssen zu Production passen. Alembic und create_app_roles.sh weiter auf dem Server ausführen. Redis und /var/linetra/files bleiben lokal.
Dann denselben Dev-up -d --build. Details: ADR-0013.
Development
Bind-Mount und Reload. Immer beide Compose-Dateien — --profile dev allein startet das Production-Backend. docker-compose.override.yml nicht mitgeben (sonst Traefik-Netz und unpublished Postgres).
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile dev up -d --build
./scripts/create_app_roles.sh
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile dev exec backend uv run alembic upgrade head
python3 scripts/setup_qgis_forms.py # optional: Formulare + Styles
Denselben up -d --build-Befehl für jeden späteren Rebuild. Alembic-DDL läuft als POSTGRES_USER (linetra_edit hat nur DML). Bei Permission denied unter /app/.venv den Stack mit beiden -f-Dateien neu starten, damit venv-init das Volume appuser (uid 1000) zuordnet.
- Frontend:
http://localhost:3000· Backend:http://localhost:8000/api/v1/health - QGIS:
localhost:3401, Userlinetra_edit, SSL aus - Schema: Alembic (
upgrade head). Optional Dump:LINETRA_BACKUP=/path/to/dump.sql ./scripts/restore_db.sh. - Stammdaten:
qgis/linetra_stammdaten.qgz(optional). Karte: Plugin, Viewsqgis_<kind>.
Backend-Tests (Development-Image):
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile dev exec backend uv run pytest -q
Production
Server: Runtime-Images, Traefik, PgBouncer — kein docker-compose.dev.yml. Ablauf und Rebuild: Deployment.
./scripts/pki/init-ca.sh # CA + Serverzertifikat; nötig für QGIS-Cert-ZIP
./scripts/pki/issue-client-cert.sh edit # optional CLI-Cert; sonst Settings → Nutzer
./scripts/deploy_server.sh # compose mtls+production + App-Rollen
docker compose exec backend uv run --no-dev alembic upgrade head
./scripts/alembic_upgrade_all.sh
./scripts/pki/verify-mtls.sh # Abnahme, nachdem mtls läuft
Nützliche Skripte
Host-Skripte, cwd Projektroot. Kurzkommentare stehen auch in den Dateiköpfen.
| Skript | Was es tut |
|---|---|
scripts/create_app_roles.sh |
Postgres-Rollen linetra_edit / linetra_read aus .env — QGIS und API, nicht die Web-Konten |
scripts/ensure_app_users.sh |
Tabelle app_users (Web-Login). Bootstrap-User seeden beim Backend-Start, solange die Tabelle leer ist |
scripts/deploy_server.sh |
Production-Bootstrap: ggf. init-ca.sh, Compose mtls+production, App-Rollen. Danach Alembic |
scripts/alembic_upgrade_all.sh |
Control-Alembic plus Tenant-Head auf jeder aktiven Mandanten-DB |
scripts/restore_db.sh |
Optionaler SQL-Dump-Import (nicht der Scratch-Start). LINETRA_BACKUP=/path/to.dump.sql |
scripts/pki/init-ca.sh |
Interne CA + PgBouncer-Serverzertifikat → pgbouncer/certs/ (Backend-Mount /certs für QGIS-Cert-ZIP) |
scripts/pki/issue-client-cert.sh |
CLI-Clientzertifikat edit\|read [name] → pgbouncer/certs/clients/. Kollegen: Einstellungen → Nutzer → QGIS-Cert-ZIP |
scripts/pki/verify-mtls.sh |
Abnahme: Login mit clients/edit.crt, Abweisung ohne Cert |
scripts/setup_qgis_forms.py |
Drag&Drop-Formulare → .qgz + layer_styles |