Nur noch eine docker-compose.yml und eine .env

Der zweite Stack unter docker/ war ein Duplikat aus Februar, das nie
mitgepflegt wurde - und genau deshalb schwer zu finden und leicht falsch zu
bedienen. Statt ihn zu loeschen (Caddy ist fuer Betreiber ohne eigenen
Reverse-Proxy zurecht gewuenscht) ist er jetzt in den Hauptstack integriert:

- caddy als optionaler Dienst mit `profiles: ["caddy"]` in docker-compose.yml.
  Ohne `--profile caddy` wird er nicht einmal angelegt - empirisch geprueft mit
  einem separaten Testprojekt: `up -d` startete nur den ungeschuetzten Dienst.
  Der laufende Stack bleibt damit unveraendert.
- Caddyfile in den Projektstamm verschoben, proxy-Ziel auf den Dienstnamen
  `opencrm` angepasst, Zertifikate unter ./data/caddy wie alle anderen Daten.
- DOMAIN, CADDY_DIR und CADDY_CONFIG_DIR in die .env.example aufgenommen.
- docker/ entfernt (Dockerfile, entrypoint.sh, docker-compose.yml,
  .env.example, README.md). Das dortige Dockerfile basierte noch auf Alpine -
  genau die Variante, von der das Projekt wegen Prisma-/TLS-Problemen bewusst
  auf node:20-slim gewechselt ist. Das gepflegte backend/Dockerfile baut
  Frontend und Backend ebenso.
- README: Abschnitt "Docker (Produktion)" ersetzt durch "Betrieb mit eigenem
  SSL", inkl. Hinweisen zu Let's-Encrypt-Limits, DNS-Voraussetzung,
  HTTPS_ENABLED und dem weiterhin offenen App-Port. Projektbaum und
  .dockerignore nachgezogen.

Geprueft: docker-compose config gueltig, caddy validate gueltig, laufende
Container unberuehrt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 19:40:43 +02:00
co-authored by Claude Opus 5
parent ee83b09ed8
commit 22501f4650
10 changed files with 70 additions and 484 deletions
+31 -36
View File
@@ -341,9 +341,8 @@ openssl rand -hex 32
| Betrieb | Datei |
|---|---|
| **Docker** (Standard, `docker-compose.yml` im Projektstamm) | **`.env` im Projektstamm** |
| **Docker** (Standard) | **`.env` im Projektstamm** |
| Backend direkt, ohne Container (Entwicklung) | `backend/.env` |
| Alternativer Caddy-Stack unter `docker/` | `docker/.env` |
Beim Docker-Betrieb reicht der Eintrag in der Stamm-`.env` `docker-compose.yml`
reicht die Variable an den Container weiter. Ein Eintrag in `backend/.env` wirkt
@@ -817,48 +816,44 @@ docker-compose down -v # Container stoppen + Daten löschen
docker-compose logs -f # Logs anzeigen
```
### Docker (Produktion)
### Betrieb mit eigenem SSL (optionaler Caddy-Dienst)
Im `docker/` Verzeichnis liegt ein komplettes Produktions-Setup:
Es gibt **eine** `docker-compose.yml` und **eine** `.env` im Projektstamm.
Standardmässig bringt der Stack **keinen** Reverse-Proxy mit die Annahme ist,
dass du bereits einen hast (nginx, Nginx Proxy Manager, Traefik) und OpenCRM
dahinter hängst.
Hast du **keinen**, kannst du Caddy als optionalen Dienst dazuschalten. Er holt
und erneuert das SSL-Zertifikat automatisch:
```bash
cd docker
# In der .env die Domain setzen
DOMAIN=crm.example.de
HTTPS_ENABLED=true
# Image bauen
docker-compose build
# Container starten
docker-compose up -d
# Logs anzeigen
docker-compose logs -f app
# Mit Caddy starten (Ports 80 + 443 müssen frei sein)
docker-compose --profile caddy up -d
```
**Komponenten:**
- **MariaDB 10.11**: Datenbank
- **App**: Backend + Frontend in einem Container
- **Caddy**: Reverse-Proxy mit automatischem SSL
Ohne `--profile caddy` bleibt Caddy aus und nichts ändert sich der Dienst
wird dann gar nicht erst angelegt.
> **Wann dieser Stack?** Wenn du **keinen** eigenen Reverse-Proxy betreibst
> Caddy holt und erneuert das SSL-Zertifikat hier selbst. Hast du bereits einen
> Proxy davor (nginx, Nginx Proxy Manager, Traefik), nimm den Stack im
> Projektstamm; er bringt bewusst keinen eigenen Proxy mit.
**Was dabei zu beachten ist:**
**Umgebungsvariablen (`docker/.env`):** vollständige Vorlage mit Erklärungen
in `docker/.env.example`
- Die Zertifikate liegen unter `./data/caddy`. Diesen Ordner **nicht löschen**,
sonst werden bei jedem Start neue Zertifikate angefordert und du läufst in
die Mengenbegrenzung von Let's Encrypt.
- Die Domain muss vorher per DNS auf den Server zeigen, sonst schlägt die
Zertifikatsausstellung fehl.
- `HTTPS_ENABLED=true` setzen das aktiviert das `Secure`-Attribut am
Refresh-Cookie und die korrekte Proxy-Erkennung.
- Der direkte App-Port (`OPENCRM_PORT`, Standard 3010) bleibt weiterhin offen.
Wenn nur Caddy von aussen erreichbar sein soll, schliesse ihn per Firewall
oder setze ihn in der `.env` auf einen Wert, den du nicht freigibst.
```env
DB_ROOT_PASSWORD=sicheres-root-passwort
DB_NAME=opencrm
DB_USER=opencrm
DB_PASSWORD=sicheres-passwort
JWT_SECRET=sehr-langer-zufaelliger-string
ENCRYPTION_KEY=64-zeichen-hex-string
DOMAIN=crm.example.com
HTTPS_ENABLED=true # Caddy terminiert TLS → Secure-Cookies an
AUDIT_HMAC_KEY= # Siegel fürs Audit-Log, siehe oben
RUN_SEED=true # Nur beim ersten Start
```
Die Konfiguration liegt in der `Caddyfile` im Projektstamm. Sie liefert
Sicherheits-Header mit und komprimiert bewusst **nicht** die API-Antworten
(BREACH-Schutz, siehe Abschnitt zum Reverse-Proxy oben).
## Projektstruktur
@@ -910,7 +905,7 @@ opencrm/
│ │ ├── types/ # TypeScript-Typen
│ │ └── App.tsx # Haupt-Komponente
│ └── package.json
├── docker/ # Docker-Deployment
├── Caddyfile # Optionaler Reverse-Proxy (nur mit --profile caddy)
│ ├── Dockerfile # Multi-Stage Build
│ ├── docker-compose.yml # Produktion (MariaDB, App, Caddy)
│ ├── Caddyfile # Reverse-Proxy mit SSL