Erste lauffähige Version
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# Serienbrief
|
||||
|
||||
Django-Webanwendung zur Erzeugung von Serienbriefen aus DOCX-Vorlagen und CSV-Empfängerlisten.
|
||||
Läuft als Compose-Stack, HTTP-only — TLS terminiert ein **vorgelagerter Nginx-Reverse-Proxy** außerhalb dieses Stacks.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
LAN-Client ──HTTPS──▶ Externer Nginx-Proxy ──HTTP──▶ App-Stack (dieses Repo)
|
||||
(TLS-Terminierung) │
|
||||
├─ nginx (intern, :8080)
|
||||
├─ web (Gunicorn / Django)
|
||||
├─ worker (Celery)
|
||||
├─ beat (Celery Scheduler)
|
||||
├─ db (PostgreSQL 16)
|
||||
├─ redis (Celery Broker)
|
||||
└─ backup (nightly pg_dump)
|
||||
```
|
||||
|
||||
Der externe Proxy muss diese Header setzen:
|
||||
- `X-Forwarded-Proto: https`
|
||||
- `X-Forwarded-For: <client>`
|
||||
- `Host: <serienbrief.lan>`
|
||||
|
||||
## Verzeichnisstruktur
|
||||
|
||||
```
|
||||
serienbrief/
|
||||
├── docker-compose.yml # Prod-Stack
|
||||
├── docker-compose.override.yml # Dev-Overrides (Auto-Merge)
|
||||
├── .env.example # Konfig-Template
|
||||
├── .devcontainer/ # VS Code Dev-Container
|
||||
├── .vscode/ # Launch, Tasks, Settings
|
||||
├── nginx/ # App-interner Nginx (HTTP)
|
||||
├── app/ # Django-Projekt
|
||||
│ ├── Dockerfile # Multi-Stage: builder/dev/runtime
|
||||
│ ├── requirements.txt
|
||||
│ ├── requirements-dev.txt
|
||||
│ ├── pyproject.toml # Ruff & Pytest
|
||||
│ ├── manage.py
|
||||
│ ├── config/ # Settings, URLs, WSGI
|
||||
│ └── mailmerge/ # Django-App: Models, Views, Tasks
|
||||
├── postgres/init/ # SQL-Init-Scripts (optional)
|
||||
├── secrets/ # Passwort-Files (chmod 600)
|
||||
└── backups/ # DB- & Media-Dumps
|
||||
```
|
||||
|
||||
## Erstinbetriebnahme (Prod)
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
nano .env # Werte setzen
|
||||
|
||||
mkdir -p secrets
|
||||
openssl rand -base64 32 > secrets/postgres_password.txt
|
||||
chmod 600 secrets/postgres_password.txt
|
||||
|
||||
docker compose -f docker-compose.yml build
|
||||
docker compose -f docker-compose.yml up -d
|
||||
docker compose exec web python manage.py createsuperuser
|
||||
```
|
||||
|
||||
Der externe Proxy zeigt dann z.B. so auf den Stack:
|
||||
```nginx
|
||||
location / {
|
||||
proxy_pass http://app-host:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
```
|
||||
|
||||
## Entwicklung in VS Code
|
||||
|
||||
### Variante A — Dev-Container (empfohlen)
|
||||
|
||||
1. VS Code öffnet das Projekt
|
||||
2. Extension **Dev Containers** installiert
|
||||
3. Command Palette → `Dev Containers: Reopen in Container`
|
||||
4. VS Code startet Compose mit Override (Build-Target `dev`, Code-Mount, Hot-Reload)
|
||||
5. Terminal im Container: `python manage.py migrate`
|
||||
6. Browser: `http://localhost:8000`
|
||||
|
||||
### Variante B — Lokal mit Compose im Hintergrund
|
||||
|
||||
```bash
|
||||
docker compose up -d # Override wird automatisch geladen
|
||||
docker compose logs -f web
|
||||
```
|
||||
|
||||
Code-Änderungen sind sofort wirksam (Bind-Mount + `runserver` mit Auto-Reload).
|
||||
|
||||
### Debugging
|
||||
|
||||
Im Container läuft `debugpy` auf Port **5678**. In VS Code:
|
||||
- Run & Debug → **Django: attach (debugpy in Container)**
|
||||
- Breakpoints überall im Code setzen
|
||||
|
||||
Alternativ Task **django: start debugpy** ausführen und attachen.
|
||||
|
||||
### Häufige VS-Code-Tasks
|
||||
|
||||
`Strg+Shift+P` → `Tasks: Run Task`:
|
||||
|
||||
| Task | Wirkung |
|
||||
|---|---|
|
||||
| compose: up | Stack starten |
|
||||
| compose: logs web | Live-Logs |
|
||||
| django: makemigrations | Migrations erzeugen |
|
||||
| django: migrate | Migrations anwenden |
|
||||
| django: shell | Django-Shell |
|
||||
| django: createsuperuser | Admin-User anlegen |
|
||||
| tests: pytest | Tests laufen lassen |
|
||||
| lint: ruff | Linting |
|
||||
|
||||
## Härtungs-Hinweise
|
||||
|
||||
- Externe Proxy-Konfiguration (TLS, HSTS, CSP, Rate-Limit) **muss** vorhanden sein
|
||||
- `APP_BIND_IP=127.0.0.1` in `.env` außer der externe Proxy läuft auf anderem Host
|
||||
- `DJANGO_ALLOWED_HOSTS` und `CSRF_TRUSTED_ORIGINS` strikt setzen
|
||||
- `SECURE_PROXY_SSL_HEADER` ist gesetzt — damit erkennt Django korrekt, dass der Client über HTTPS kam
|
||||
- Postgres und Redis sind **nicht** nach außen exponiert (nur im backend-Netz)
|
||||
- Container laufen non-root, `read_only`, mit `no-new-privileges`
|
||||
- Backups regelmäßig auf zweites System spiegeln (Borg/Restic)
|
||||
Reference in New Issue
Block a user