services: # --------------------------------------------------------------------------- # HAProxy: einziger öffentlich erreichbarer Dienst (Ports 80/443 + ggf. # weitere, siehe generated/docker-compose.override.yml für tcp_services). # Aufgaben: IP-Filterung (L4, vor TLS-Handshake) + Passthrough zu Caddy. # --------------------------------------------------------------------------- haproxy: image: ${HAPROXY_IMAGE:-haproxy:3.2-alpine} container_name: edge-haproxy restart: unless-stopped depends_on: - caddy ports: - "80:80" - "443:443" volumes: - ./generated/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro - ./generated/acl:/usr/local/etc/haproxy/acl:ro networks: - edge cap_drop: - ALL cap_add: - NET_BIND_SERVICE security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp healthcheck: test: ["CMD", "haproxy", "-c", "-f", "/usr/local/etc/haproxy/haproxy.cfg"] interval: 30s timeout: 5s retries: 3 logging: driver: json-file options: max-size: "10m" max-file: "3" # --------------------------------------------------------------------------- # Caddy: TLS-Terminierung + automatisches Let's Encrypt + Host-basiertes # Routing zu den eigentlichen Backends. Nicht öffentlich exponiert - # erreichbar nur über HAProxy im "edge"-Netzwerk. # --------------------------------------------------------------------------- caddy: image: ${CADDY_IMAGE:-caddy:2.11-alpine} container_name: edge-caddy restart: unless-stopped expose: - "80" - "443" volumes: - ./generated/Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config networks: - edge cap_drop: - ALL cap_add: - NET_BIND_SERVICE security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp healthcheck: test: ["CMD", "caddy", "version"] interval: 30s timeout: 5s retries: 3 logging: driver: json-file options: max-size: "10m" max-file: "3" networks: # Externes Netzwerk, damit andere docker-compose-Projekte (Mailcow, Checkmk, # eigene Anwendungen, ...) sich anhängen und per Containername erreichbar # sind, ohne dass dieser Stack sie kennen oder verwalten muss. # # Einmalig anlegen: docker network create edge edge: external: true volumes: caddy_data: caddy_config: