44 lines
1.3 KiB
YAML
44 lines
1.3 KiB
YAML
services:
|
||
app:
|
||
build: .
|
||
# Rootless: Prozess läuft als UID:GID 10001:10001 (siehe Dockerfile USER).
|
||
# Entspricht der festen Identität im Image – auch beim Deployment mit
|
||
# fertigem Registry-Image setzen (siehe docker-compose.deploy.yml).
|
||
user: "10001:10001"
|
||
# Kein ports:-Mapping: Die App ist nur im internen Compose-Netz erreichbar.
|
||
# Nach außen geht es ausschließlich über den Caddy-Reverse-Proxy (443/HTTPS).
|
||
expose:
|
||
- "3000"
|
||
environment:
|
||
# Interner Direktzugriff für den Erinnerungs-Scheduler (kein Hairpin über den Proxy nötig).
|
||
- APP_INTERNAL_URL=http://app:3000
|
||
volumes:
|
||
- gutschein-data:/data
|
||
env_file: [.env]
|
||
restart: unless-stopped
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
|
||
caddy:
|
||
image: caddy:2-alpine
|
||
restart: unless-stopped
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
- "443:443/udp" # HTTP/3 (optional, schadet nicht)
|
||
volumes:
|
||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||
- caddy-data:/data
|
||
- caddy-config:/config
|
||
environment:
|
||
DOMAIN: ${DOMAIN:?DOMAIN muss in .env gesetzt sein (z. B. gutscheine.example.de)}
|
||
depends_on:
|
||
- app
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
|
||
volumes:
|
||
gutschein-data: {}
|
||
caddy-data: {}
|
||
caddy-config: {}
|