name: drivervault

# TLS overlay — put a public hostname and a real certificate in front of the
# stack. Layer it on top of either base file:
#
#   docker compose -f docker-compose.prod.yml -f docker-compose.tls.yml up -d
#
# What it changes:
#   • Caddy terminates TLS on :443 and proxies everything to the Web App BFF,
#     which already carries /api/ and /ocpp/ through to the API Server. One
#     hostname serves browsers and chargers alike.
#   • The charger endpoint the panel hands out becomes wss://$DV_DOMAIN/ocpp/…,
#     so OCPP_REQUIRE_TLS goes back on and the control token stops crossing the
#     network in the clear.
#
# Requirements, none of which this file can arrange for you:
#   • DV_DOMAIN resolves to this host from the public internet, and ports 80 and
#     443 reach it (Caddy needs :80 for the ACME challenge, and keeps it for the
#     redirect afterwards).
#   • The charger can resolve DV_DOMAIN too. On a LAN behind NAT that usually
#     means hairpin NAT or a split-DNS entry pointing the name at 10.2.1.10 —
#     otherwise the charger looks up a public address it cannot route to.

services:
  caddy:
    image: "${CADDY_IMAGE:-caddy:2-alpine}"
    container_name: drivervault-caddy
    restart: unless-stopped
    depends_on:
      web-app:
        condition: service_healthy
    environment:
      DV_DOMAIN: "${DV_DOMAIN:?set DV_DOMAIN in .env}"
      # Let's Encrypt sends expiry warnings here if renewal ever stops working.
      DV_ACME_EMAIL: "${DV_ACME_EMAIL:?set DV_ACME_EMAIL in .env}"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      # Certificates live here. Keep the volume: wiping it re-issues on next
      # boot and Let's Encrypt rate-limits that.
      - caddy_data:/data
      - caddy_config:/config

  api-server:
    environment:
      # Derived from the one hostname, so there is a single thing to set.
      OCPP_REQUIRE_TLS: "true"
      OCPP_PUBLIC_URL: "wss://${DV_DOMAIN}"
      CORS_ALLOW_ORIGINS: "https://${DV_DOMAIN}"

  web-app:
    environment:
      # Caddy terminates TLS and says so in X-Forwarded-Proto. Believe it —
      # that header is now set by the proxy in front, not by whoever dialed in.
      TRUST_FORWARDED_PROTO: "true"

volumes:
  caddy_data:
  caddy_config:
