# Traefik reverse proxy + cert manager for chatmail. # Use this instead of docker-compose.yaml when Traefik manages TLS certificates. # # Required .env vars: # MAIL_DOMAIN=chat.example.com # ACME_EMAIL=admin@example.com # # Usage: # cp docker/example-traefik.env .env # docker compose -f docker/docker-compose-traefik.yaml build # docker compose -f docker/docker-compose-traefik.yaml up -d services: chatmail: build: context: ../ dockerfile: docker/chatmail_relay.dockerfile image: chatmail-relay:latest restart: unless-stopped container_name: chatmail depends_on: traefik-certs-dumper: condition: service_started cgroup: host tty: true tmpfs: - /tmp - /run - /run/lock logging: driver: json-file options: max-size: "10m" max-file: "3" environment: MAIL_DOMAIN: $MAIL_DOMAIN CMDEPLOY_STAGES: ${CMDEPLOY_STAGES:-} CHATMAIL_NOACME: "true" PATH_TO_SSL: /var/lib/acme/live/${MAIL_DOMAIN} ports: - "25:25" - "143:143" - "465:465" - "587:587" - "993:993" volumes: - /sys/fs/cgroup:/sys/fs/cgroup:rw - chatmail-data:/home - chatmail-dkimkeys:/etc/dkimkeys - traefik-certs:/var/lib/acme/live:ro labels: - traefik.enable=true - traefik.http.services.chatmail.loadbalancer.server.scheme=https - traefik.http.services.chatmail.loadbalancer.server.port=443 - traefik.http.services.chatmail.loadbalancer.serverstransport=insecure@file - traefik.http.routers.chatmail.rule=Host(`${MAIL_DOMAIN}`) || Host(`mta-sts.${MAIL_DOMAIN}`) || Host(`www.${MAIL_DOMAIN}`) - traefik.http.routers.chatmail.tls=true - traefik.http.routers.chatmail.tls.certresolver=letsEncrypt traefik: image: traefik:v3.3 container_name: traefik restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" command: - "--configFile=/config.yaml" - "--certificatesresolvers.letsEncrypt.acme.email=${ACME_EMAIL}" network_mode: host depends_on: traefik-init: condition: service_completed_successfully volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./traefik/config.yaml:/config.yaml:ro - traefik-data:/data - ./traefik/dynamic-configs:/dynamic/conf:ro traefik-init: image: alpine:latest restart: "no" entrypoint: sh -c 'touch /data/acme.json && chmod 600 /data/acme.json' volumes: - traefik-data:/data traefik-certs-dumper: image: ldez/traefik-certs-dumper:v2.10.0 restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" depends_on: - traefik entrypoint: sh -c ' apk add openssl && while ! [ -e /data/acme.json ] || ! [ "$$(jq ".[] | .Certificates | length" /data/acme.json | jq -s "add")" != "0" ]; do sleep 1 ; done && traefik-certs-dumper file --version v3 --watch --domain-subdir=true --source /data/acme.json --dest /certs --post-hook "sh /post-hook.sh"' volumes: - traefik-data:/data:ro - traefik-certs:/certs - ./traefik/post-hook.sh:/post-hook.sh:ro volumes: chatmail-data: chatmail-dkimkeys: traefik-data: traefik-certs: