Files
traefik/traefik.yml
Paul R Kartchner 33e90493b7 Prod: switch Let's Encrypt from HTTP-01 to Route 53 DNS-01
Certificates no longer depend on public port 80 reaching this host, and a
name can be certified before its A record points here (backyardhoneycomb.com
migration). Uses IAM user traefik-prod-dns01 from .env (AWS_REGION must be
set; the SDK needs it even for global Route 53), allowed only to write
_acme-challenge.* TXT records in the pkartchner.com and backyardhoneycomb.com
zones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 14:47:07 -07:00

81 lines
2.6 KiB
YAML

# Traefik static configuration — DEFAULT / PRODUCTION.
#
# Selected by TRAEFIK_STATIC_CONFIG in .env (defaults to this file).
# The dev host uses traefik.dev.yml, which differs ONLY in the ACME challenge
# type, because public port 80 forwards to prod so HTTP-01 cannot work there.
#
# NOTE: Traefik does NOT interpolate environment variables in this file. Any
# secret must be a docker-compose label instead, where compose substitutes it
# from .env. That is why the CrowdSec bouncer is defined in docker-compose.yml.
api:
dashboard: true
debug: false
experimental:
plugins:
bouncer:
moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
version: v1.3.5
geoblock:
moduleName: github.com/PascalMinder/geoblock
version: v0.2.8
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
permanent: true
# priority 1 keeps this redirect BELOW normal routers, which default
# to a priority derived from rule length. That is what allows basil's
# Host(`localhost`) HTTP router to keep serving without redirecting.
# Do not raise this value.
priority: 1
https:
address: ":443"
# Backends here use self-signed certs (harbor, etc). This disables verification
# of upstream TLS for ALL services — matches prod, but it is a real weakening.
# Prefer per-service serversTransport if you ever narrow this.
serversTransport:
insecureSkipVerify: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik
httpClientTimeout: 0
file:
filename: /config.yml
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: pkartch@gmail.com
storage: acme.json
# DNS-01 via Route 53 (since 2026-11-03; was HTTP-01). Proves control with
# an _acme-challenge TXT record, so certificates no longer depend on public
# port 80 reaching this host, and a name can be certified before its A
# record points here (e.g. a site migration). Credentials: IAM user
# traefik-prod-dns01 in .env, allowed ONLY to write _acme-challenge.* TXT
# records in the pkartchner.com and backyardhoneycomb.com zones.
dnsChallenge:
provider: route53
# Check propagation against public resolvers: Pi-hole answers for
# internal names and never sees the TXT record.
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
log:
level: INFO
accessLog:
filePath: "/var/log/traefik/access.log"