# DNS-01 ACME override — applied ONLY for managed-DNS deploys (the
# DNS01_PROVIDERS table: cloudflare, hetzner, digitalocean, linode, vultr,
# scaleway).
#
# Activated by the deploy bundler (src/lib/deploy/bundle.js -> composeFileFlags)
# when the deploy manages DNS via an API. It is appended AFTER
# docker-compose.prod.yml, so the `command:` below REPLACES the base Traefik
# command — Compose replaces sequences, it does not merge them. That means the
# full command list must be restated here; keep every non-ACME flag in sync
# with docker-compose.prod.yml. Only the two `httpchallenge` lines are swapped
# for the three `dnschallenge` lines.
#
# Why: these providers expose an API lego (Traefik's ACME client) uses to
# solve the DNS-01 challenge by writing a TXT record. This removes the HTTP-01
# race against A-record propagation, so the deploy no longer needs the
# DNS-propagation poll or the Traefik cert self-heal. `manual` DNS keeps the
# base HTTP-01 path (this override is not applied for it).
#
# Tokens: lego picks the provider from ACME_DNS_PROVIDER and reads that
# provider's own token var (names verified against go-acme.github.io/lego/dns/;
# they are NOT uniform — DigitalOcean's is DO_AUTH_TOKEN, not the CLI's
# DIGITALOCEAN_TOKEN, and Scaleway's is the plugin-native SCW_SECRET_KEY, not
# the operator-facing SCALEWAY_SECRET_KEY). Hetzner uses the consolidated Cloud API token
# HETZNER_API_TOKEN (lego v4.27+, Traefik >= 3.6.6; we pin v3.6.11) — the same
# token as server ops. Every var is passed through and an unset one
# interpolates to empty, so only the active provider's token is ever
# populated; the bundler writes exactly that one into .env. Drift-guarded by
# tests/unit/deploy/acme.test.ts.
services:
  traefik:
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.endpoint=tcp://docker-socket-proxy:2375"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.file.directory=/etc/traefik/dynamic"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=${ACME_DNS_PROVIDER}"
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53"
      # Settle floor before lego's propagation check (0s unless the provider's
      # legoTuningEnv sets it — DigitalOcean: 90s, see the registry row): on
      # anycast authoritative DNS, lego's vantage converging does not mean the
      # CA's validation vantage has — give the record wall-time in the zone.
      - "--certificatesresolvers.letsencrypt.acme.dnschallenge.propagation.delaybeforechecks=${ACME_DNS_DELAY_BEFORE_CHECKS:-0s}"
      - "--certificatesresolvers.letsencrypt.acme.email={{ADMIN_EMAIL}}"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      # ACME_DISARMED_CA_SERVER first (compose-ha single-active-issuer
      # policy, src/lib/deploy/acme-role.js): set on the STANDBY node only,
      # pointing lego at a reserved-.invalid host so it never reaches a CA
      # and never writes challenge TXT records. Empty/unset falls through
      # to the real ACME_CA_SERVER (staging in e2e) or the prod default.
      - "--certificatesresolvers.letsencrypt.acme.caserver=${ACME_DISARMED_CA_SERVER:-${ACME_CA_SERVER:-https://acme-v02.api.letsencrypt.org/directory}}"
      - "--log.level=WARN"
    environment:
      ACME_DNS_PROVIDER: ${ACME_DNS_PROVIDER:-}
      CF_DNS_API_TOKEN: ${CF_DNS_API_TOKEN:-}
      HETZNER_API_TOKEN: ${HETZNER_API_TOKEN:-}
      # Hetzner lego tuning (DNS01_PROVIDERS legoTuningEnv): propagation
      # latency insurance for degraded windows — see the registry row.
      HETZNER_PROPAGATION_TIMEOUT: ${HETZNER_PROPAGATION_TIMEOUT:-}
      DO_AUTH_TOKEN: ${DO_AUTH_TOKEN:-}
      # DigitalOcean lego tuning (DNS01_PROVIDERS legoTuningEnv): DO's
      # authoritative anycast outlives lego's 60s default propagation wait,
      # churning challenge TXT values — see the registry row's rationale.
      DO_PROPAGATION_TIMEOUT: ${DO_PROPAGATION_TIMEOUT:-}
      ACME_DNS_DELAY_BEFORE_CHECKS: ${ACME_DNS_DELAY_BEFORE_CHECKS:-}
      LINODE_TOKEN: ${LINODE_TOKEN:-}
      VULTR_API_KEY: ${VULTR_API_KEY:-}
      # Vultr lego tuning (DNS01_PROVIDERS legoTuningEnv): the zone's
      # authoritative frontends negatively cache queried-before-created
      # names, so lego's first check must wait out record publication —
      # see the registry row's rationale.
      VULTR_PROPAGATION_TIMEOUT: ${VULTR_PROPAGATION_TIMEOUT:-}
      SCW_SECRET_KEY: ${SCW_SECRET_KEY:-}
