* chore(MP-21): snapshot pre-refactor state (Epic 1)
* chore(MP-22): scaffold new repo structure, relocate Docker Compose, move frontend/backend modules, update Makefile; add docs mapping and env template
* MP-22 Epic 2: Erfolgreich umgesetzt und verifiziert
* MP-23 Epic 3: Gradle/Build Governance zentralisieren
* MP-23 Epic 3: Gradle/Build Governance zentralisieren
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(devops)!: Docker-SSoT (.env) konsolidiert, Compose-Mounts ergänzt, Makefile entfernt
- ENV Single Source of Truth
- docker/.env.example neu (inkl. REDIS_PASSWORD, Ports, Build-Overrides)
- config/.env(.example) als DEPRECATED markiert (Verweis auf docker/.env[.example])
- Docker Compose vereinheitlicht (docker/docker-compose.yaml)
- Postgres: zentralen postgresql.conf mounten (../config/postgres/postgresql.conf)
und Start mit -c config_file=/etc/postgresql/postgresql.conf
- Redis: zentralen redis.conf mounten (../config/redis/redis.conf)
und Start via "redis-server … ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}"
- Web-Nginx: ../config/nginx/nginx.prod.conf → /etc/nginx/nginx.conf (ro)
- Monitoring: Prometheus/Grafana nutzen ../config/monitoring/* als SSoT
- Frontend/DI/Network (MP-23 Grundlage)
- :frontend:core:network Modul mit Koin `apiClient` (Ktor + JSON/Retry/Timeout/Logging)
- Plattform-Basis-URL-Auflösung (JVM: ENV API_BASE_URL; JS: globalThis.API_BASE_URL / Same-Origin)
- Web index.html setzt API_BASE_URL (Query `?apiBaseUrl=…` > Same-Origin > Fallback)
- Build/Gradle & Module-Refs
- settings.gradle.kts: neue Frontend-/Backend-Pfade bereits inkludiert
- Features/Shell: Abhängigkeiten auf :frontend:shared / :frontend:core:* angepasst
- Ping-API-Refs auf :backend:services:ping:ping-api vereinheitlicht
- Dockerfiles angepasst
- backend/infrastructure/gateway/Dockerfile → Tasks/Pfade auf :backend:gateway
- backend/services/ping/Dockerfile → Tasks/Pfade auf :backend:services:ping:ping-service
- Static Analysis / Guards
- config/detekt/detekt.yml hinzugefügt
- Leichter Arch-Guard (Frontend) gegen manuelle Authorization-Header vorbereitet
- Doku
- docs/ARCHITECTURE.md (Struktur, Mapping, Next Steps) ergänzt
- docs/adr/README.md angelegt
BREAKING CHANGES:
- Makefile komplett entfernt (bitte direkt `docker compose` verwenden)
- ENV-Quelle ist jetzt docker/.env (statt config/.env oder Root)
- Compose-Datei unter docker/docker-compose.yaml (nicht mehr compose.yaml im Repo-Root)
Verifikation (lokal):
- ENV anlegen: `cp docker/.env.example docker/.env` (Werte anpassen)
- Compose prüfen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml config`
- Infrastruktur: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle up -d postgres redis keycloak web-app`
- Services bauen: `docker compose --env-file docker/.env -f docker/docker-compose.yaml -p meldestelle build api-gateway ping-service --no-cache --progress=plain`
Refs: MP-22 (Epic 2), MP-23 (Epic 3)
* chore(ci): Workflows an Docker-SSoT & neue Struktur angepasst, minimaler SSoT-Guard
- ssot-guard.yml: Option B (minimal) → `docker compose -f docker/docker-compose.yaml config` als Lint
- integration-tests.yml: `./gradlew staticAnalysis` vor Integrationstests
- docs-kdoc-sync.yml: Dokka-Task Fallback (dokkaGfmAll || dokkaGfm), YouTrack-Sync nur wenn Script vorhanden
- deploy-proxmox.yml: Compose-Pfade auf docker/docker-compose.yaml + `--env-file docker/.env`; Build/Test Schritte vereinheitlicht
- ci-main.yml: SSoT-Skripte per `if: hashFiles(...)` guarded, Compose-Lint Fallback; OpenAPI‑Pfad → backend/gateway; ADR‑Pfade → docs/adr/**; `staticAnalysis` in Build integriert
- youtrack-sync.yml: unverändert (funktional)
Refs: MP-22, MP-23
* chore(ci): Workflows an Docker-SSoT & neue Struktur angepasst, minimaler SSoT-Guard
- ssot-guard.yml: Option B (minimal) → `docker compose -f docker/docker-compose.yaml config` als Lint
- integration-tests.yml: `./gradlew staticAnalysis` vor Integrationstests
- docs-kdoc-sync.yml: Dokka-Task Fallback (dokkaGfmAll || dokkaGfm), YouTrack-Sync nur wenn Script vorhanden
- deploy-proxmox.yml: Compose-Pfade auf docker/docker-compose.yaml + `--env-file docker/.env`; Build/Test Schritte vereinheitlicht
- ci-main.yml: SSoT-Skripte per `if: hashFiles(...)` guarded, Compose-Lint Fallback; OpenAPI‑Pfad → backend/gateway; ADR‑Pfade → docs/adr/**; `staticAnalysis` in Build integriert
- youtrack-sync.yml: unverändert (funktional)
Refs: MP-22, MP-23
* fix(ci): create .env from example before validating compose config
* fix(ci): update ssot-guard filename (.yaml) and sync workflow state
* fixing
* fix(webpack): correct sql.js fallback configuration for webpack 5
231 lines
6.6 KiB
Markdown
231 lines
6.6 KiB
Markdown
# Docker-Production Deployment
|
|
|
|
---
|
|
|
|
guideline_type: "technology"
|
|
scope: "docker-production"
|
|
audience: ["developers", "devops", "ai-assistants"]
|
|
last_updated: "2025-09-15"
|
|
dependencies: ["docker-overview.md", "docker-architecture.md"]
|
|
related_files: ["docker-compose.yml", "config/nginx/nginx.prod.conf", "config/ssl/*"]
|
|
ai_context: "Production-Deployment, Security-Hardening, SSL/TLS-Konfiguration und Ressourcenverwaltung"
|
|
|
|
---
|
|
|
|
## 🚀 Production-Deployment
|
|
|
|
### Security Hardening
|
|
|
|
Unsere Production-Konfiguration implementiert umfassende Sicherheitsmaßnahmen:
|
|
|
|
#### 🔒 SSL/TLS Everywhere
|
|
|
|
```bash
|
|
# TLS-Zertifikate vorbereiten
|
|
mkdir -p config/ssl/{postgres,redis,keycloak,grafana,prometheus,nginx}
|
|
|
|
# Let's Encrypt Zertifikate generieren
|
|
certbot certonly --dns-route53 -d api.meldestelle.at
|
|
certbot certonly --dns-route53 -d auth.meldestelle.at
|
|
certbot certonly --dns-route53 -d monitor.meldestelle.at
|
|
```
|
|
|
|
#### 🛡️ Environment Variables
|
|
|
|
> **🤖 AI-Assistant Hinweis:**
|
|
> Alle Passwörter werden in der Produktion mit starker Verschlüsselung generiert:
|
|
> - **PostgreSQL/Redis:** `openssl rand -base64 32`
|
|
> - **Keycloak:** Separate Admin-Credentials
|
|
> - **Monitoring:** Grafana/Prometheus Admin-Access
|
|
|
|
**Erforderliche Production-Variablen:**
|
|
|
|
```bash
|
|
# Datenschutz und Sicherheit
|
|
export POSTGRES_USER=meldestelle_prod
|
|
export POSTGRES_PASSWORD=$(openssl rand -base64 32)
|
|
export POSTGRES_DB=meldestelle_prod
|
|
export REDIS_PASSWORD=$(openssl rand -base64 32)
|
|
|
|
# Keycloak Admin
|
|
export KEYCLOAK_ADMIN=admin
|
|
export KEYCLOAK_ADMIN_PASSWORD=$(openssl rand -base64 32)
|
|
export KC_DB_PASSWORD=${POSTGRES_PASSWORD}
|
|
export KC_HOSTNAME=auth.meldestelle.at
|
|
|
|
# Monitoring
|
|
export GF_SECURITY_ADMIN_USER=admin
|
|
export GF_SECURITY_ADMIN_PASSWORD=$(openssl rand -base64 32)
|
|
export GRAFANA_HOSTNAME=monitor.meldestelle.at
|
|
export PROMETHEUS_HOSTNAME=metrics.meldestelle.at
|
|
|
|
# Kafka Security
|
|
export KAFKA_BROKER_ID=1
|
|
export KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
|
|
```
|
|
|
|
#### 🌐 Reverse Proxy Configuration
|
|
|
|
**nginx.prod.conf** Beispiel:
|
|
|
|
```nginx
|
|
upstream api_backend {
|
|
server api-gateway:8081;
|
|
keepalive 32;
|
|
}
|
|
|
|
upstream auth_backend {
|
|
server keycloak:8443;
|
|
keepalive 32;
|
|
}
|
|
|
|
upstream monitoring_backend {
|
|
server grafana:3443;
|
|
keepalive 32;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name api.meldestelle.at;
|
|
|
|
ssl_certificate /etc/ssl/nginx/api.meldestelle.at.crt;
|
|
ssl_certificate_key /etc/ssl/nginx/api.meldestelle.at.key;
|
|
|
|
# Security headers
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
add_header X-Frame-Options DENY always;
|
|
add_header X-Content-Type-Options nosniff always;
|
|
add_header Referrer-Policy strict-origin-when-cross-origin always;
|
|
|
|
location / {
|
|
proxy_pass http://api_backend;
|
|
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 $scheme;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Resource Limits
|
|
|
|
Alle Production-Services haben definierte Resource-Limits:
|
|
|
|
```yaml
|
|
# Beispiel für Resource-Management
|
|
services:
|
|
postgres:
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 1G
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 512M
|
|
cpus: '0.25'
|
|
|
|
api-gateway:
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 256M
|
|
cpus: '0.25'
|
|
```
|
|
|
|
## 🎯 AI-Assistenten: Production-Schnellreferenz
|
|
|
|
### Production-Domains
|
|
|
|
- **API:** api.meldestelle.at (HTTPS)
|
|
- **Auth:** auth.meldestelle.at (HTTPS)
|
|
- **Monitoring:** monitor.meldestelle.at (HTTPS)
|
|
- **Metrics:** metrics.meldestelle.at (HTTPS)
|
|
|
|
### Security-Checkliste
|
|
|
|
- [ ] SSL/TLS-Zertifikate installiert und gültig
|
|
- [ ] Alle Passwörter mit `openssl rand -base64 32` generiert
|
|
- [ ] Nginx Security Headers konfiguriert
|
|
- [ ] Resource Limits für alle Services definiert
|
|
- [ ] Firewall-Regeln nur für notwendige Ports
|
|
- [ ] Container laufen als non-root User
|
|
|
|
### Production-Befehle
|
|
|
|
| Aufgabe | Befehl | Beschreibung |
|
|
|---------------------|----------------------------------------------------|---------------------------|
|
|
| Zertifikat erneuern | `certbot renew` | Let's Encrypt Zertifikate |
|
|
| SSL-Status prüfen | `openssl s_client -connect api.meldestelle.at:443` | SSL-Verbindung testen |
|
|
| Resource-Usage | `docker stats` | Container-Ressourcen |
|
|
| Security-Scan | `docker scan <image>` | Vulnerability Check |
|
|
| Log-Rotation | `docker system prune -f` | Alte Logs bereinigen |
|
|
|
|
### Environment-Variablen Validierung
|
|
|
|
```bash
|
|
# Production-Variablen prüfen
|
|
echo "Postgres User: $POSTGRES_USER"
|
|
echo "Keycloak Hostname: $KC_HOSTNAME"
|
|
echo "Grafana Hostname: $GRAFANA_HOSTNAME"
|
|
|
|
# Passwort-Stärke prüfen (sollte 32+ Zeichen haben)
|
|
echo ${#POSTGRES_PASSWORD} # Sollte 44+ ausgeben
|
|
echo ${#KEYCLOAK_ADMIN_PASSWORD} # Sollte 44+ ausgeben
|
|
```
|
|
|
|
### Deployment-Workflow
|
|
|
|
```bash
|
|
# 1. Environment-Variablen setzen
|
|
source .env.production
|
|
|
|
# 2. SSL-Zertifikate prüfen
|
|
certbot certificates
|
|
|
|
# 3. Services mit Production-Konfiguration starten
|
|
docker-compose -f docker-compose.yaml -f docker-compose.prod.yml up -d
|
|
|
|
# 4. Health-Checks durchführen
|
|
curl -f https://api.meldestelle.at/actuator/health
|
|
curl -f https://auth.meldestelle.at/health/ready
|
|
curl -f https://monitor.meldestelle.at/api/health
|
|
|
|
# 5. SSL-Konfiguration validieren
|
|
curl -I https://api.meldestelle.at | grep -i security
|
|
```
|
|
|
|
### Backup-Strategie
|
|
|
|
```bash
|
|
# Datenbank-Backup
|
|
docker-compose exec postgres pg_dump -U $POSTGRES_USER $POSTGRES_DB > backup_$(date +%Y%m%d).sql
|
|
|
|
# Konfigurationsdateien sichern
|
|
tar -czf config_backup_$(date +%Y%m%d).tar.gz config/
|
|
|
|
# Docker-Volumes sichern
|
|
docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres_backup_$(date +%Y%m%d).tar.gz /data
|
|
```
|
|
|
|
### Monitoring-Integration
|
|
|
|
```bash
|
|
# Prometheus-Targets prüfen
|
|
curl -s https://metrics.meldestelle.at/api/v1/targets | jq '.data.activeTargets[].health'
|
|
|
|
# Grafana-Dashboard Status
|
|
curl -s https://monitor.meldestelle.at/api/health | jq '.database'
|
|
```
|
|
|
|
---
|
|
|
|
**Navigation:**
|
|
- [docker-overview](./docker-overview.md) - Grundlagen und Philosophie
|
|
- [docker-architecture](./docker-architecture.md) - Container-Services und Struktur
|
|
- [docker-development](./docker-development.md) - Entwicklungsworkflow
|
|
- [docker-monitoring](./docker-monitoring.md) - Observability
|
|
- [docker-troubleshooting](./docker-troubleshooting.md) - Problemlösung
|