Let's Encrypt z Dockerem i Traefik — automatyczne HTTPS dla każdej usługi
bezpieczenstwo,linux,docker,traefik,poradnik,wwwTo kontynuacja wpisu o Let's Encrypt z 2016 roku opartego na acme.sh i Apache. Tamto rozwiązanie działało, ale ręczne zarządzanie certyfikatami nie skaluje się, gdy prowadzisz wiele usług w Dockerze. Traefik rozwiązuje to w całości.
Traefik to reverse proxy zaprojektowany dla środowisk kontenerowych. Obserwuje Docker socket, wykrywa uruchomione kontenery i automatycznie pobiera certyfikaty Let's Encrypt — bez certbota, bez crona, bez ręcznej konfiguracji per domena.
Konfiguracja składa się z dwóch części: jedna instancja Traefik działająca cały czas na serwerze oraz etykiety przy każdej usłudze, które mówią Traefik jak routować ruch i dla jakiej domeny wystawić certyfikat.
Część 1 — docker-compose.yml dla Traefik
Uruchamiany raz na serwerze. Wszystkie pozostałe usługi przechodzą przez niego.
services:
traefik:
image: traefik:${TRAEFIK_VERSION}
container_name: traefik
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# globalne przekierowanie HTTP → HTTPS
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
# Let's Encrypt
- "--certificatesResolvers.le.acme.email=${ACME_EMAIL}"
- "--certificatesResolvers.le.acme.storage=acme.json"
- "--certificatesResolvers.le.acme.tlsChallenge=true"
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./acme.json:/acme.json
labels:
- traefik.http.middlewares.gzip.compress=true
networks:
web:
external: true
Kilka rzeczy wartych uwagi:
exposedbydefault=false— Traefik ignoruje kontenery, chyba że jawnie się zgłoszą przez etykiety. Nic nie zostaje przypadkowo wystawione na zewnątrz.- TLS challenge — Traefik obsługuje weryfikację domeny bezpośrednio na porcie 443. Nie trzeba tymczasowo otwierać portu 80.
acme.json— certyfikaty są zapisywane na dysku i przeżywają restarty kontenera. Przed pierwszym uruchomieniem utwórz plik i ustaw odpowiednie uprawnienia:
touch acme.json && chmod 600 acme.json
Traefik odmówi uruchomienia przy zbyt szerokich uprawnieniach.
- Zewnętrzna sieć
web— tworzysz ją raz:
docker network create web
Każda usługa potrzebująca routingu HTTP/S dołącza do tej sieci.
Część 2 — Certyfikaty testowe (staging)
Przed przejściem na produkcję przetestuj z serwerem staging Let's Encrypt, żeby nie trafić na limity:
# dodaj do sekcji command w traefik:
- "--log.level=DEBUG"
- "--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
Certyfikaty stagingowe nie są zaufane przez przeglądarki, ale funkcjonalnie działają identycznie. Usuń te linie gdy wszystko działa.
Część 3 — Dodanie usługi
Tu widać zwrot z inwestycji. Dowolny kontener dostaje HTTPS przez dodanie czterech etykiet:
services:
myapp:
image: myapp:latest
networks:
- web
labels:
- traefik.enable=true
- traefik.http.routers.myapp.rule=Host(`myapp.example.com`)
- traefik.http.routers.myapp.entrypoints=websecure
- traefik.http.routers.myapp.tls.certresolver=le
networks:
web:
external: true
Traefik wykrywa kontener, pobiera certyfikat od Let's Encrypt i zaczyna routować ruch — bez konfiguracji nginx, bez uruchamiania certbota, bez crona. Odnowienia dzieją się automatycznie w tle.
Alternatywa bez Dockera
Jeśli nie używasz Dockera, Certbot z wtyczką nginx to standardowe podejście: apt install certbot python3-certbot-nginx, certbot --nginx -d mojastrona.pl, a timer systemd zajmuje się odnowieniami. Sprawdza się dobrze na jednym serwerze z kilkoma stronami. Gdy usług jest więcej, podejście z Traefik zaczyna się opłacać.