Serwer domowy Docker Compose: Traefik, TLS i monitorowanie aktualizacji
Część 4 z 7 serii Homelab na Raspberry Pi

Management Summary
Domowy serwer może udostępniać kilka lokalnych usług przez wspólnie zarządzany punkt dostępu. Opisany układ kieruje żądania do właściwej aplikacji, odnawia certyfikaty szyfrowanych połączeń i informuje o nowych wersjach programów. Automatyzacja tych czynności ułatwia utrzymanie niewielkiej instalacji na Raspberry Pi. Zadania pozostają odrębne: powiadomienie o aktualizacji nie instaluje poprawki. Jedno urządzenie nadal może ulec awarii, dlatego zapisane dane wymagają kopii umożliwiających odtworzenie.
Spis treści
Serwer domowy z jasno podzielonymi zadaniami
Traefik kieruje żądania do kontenerów Dockera i może pobierać oraz odnawiać certyfikaty TLS przez Let’s Encrypt. TLS szyfruje połączenie między przeglądarką a Traefikiem. Docker Compose zapisuje konfigurację usług w pliku. Watchtower może sprawdzać zmiany obrazów kontenerów. Takie narzędzia ograniczają rutynową pracę; kopie zapasowe, monitoring i świadomie planowane aktualizacje nadal są potrzebne.
Poniższy przykład stanowi punkt wyjścia dla oddzielnego środowiska testowego na Raspberry Pi z Docker Engine i Compose. Architektura obrazów, zgodność z API Dockera oraz wybrane wersje wymagają sprawdzenia na docelowym systemie. Jeden Pi i jeden kontener na aplikację nie zapewniają wysokiej dostępności.

1. Przygotowanie DNS, obrazów i plików certyfikatów
HTTP-01 wymaga kontrolowanej administracyjnie domeny i portu 80 dostępnego z internetu. Publiczne rekordy A/AAAA, przekierowanie portów oraz reguły zapory IPv4/IPv6 muszą być spójne. Porty 80 i 443 hosta muszą być wolne. DNS-01 umożliwia wydanie certyfikatów bez połączeń przychodzących, ale nie zapewnia dostępu do serwera za CGNAT. Przy CGNAT kilku klientów operatora współdzieli publiczny adres IPv4; zwykłe przekierowanie portu na domowym routerze wtedy nie wystarcza.
W zapisywalnym katalogu projektu poniższe polecenia tworzą pliki certyfikatów bez opróżniania istniejących plików. Proces kontenera potrzebuje odpowiedniej własności plików oraz uprawnień 600. Pliki zawierają klucze prywatne i wymagają chronionych kopii zapasowych.
mkdir -p data
touch data/acme-staging.json data/acme-production.json
chmod 600 data/acme-staging.json data/acme-production.jsonGłówna konfiguracja otrzymuje nazwę compose.yaml. Plik .env w tym samym katalogu definiuje TRAEFIK_IMAGE, SOCKET_PROXY_IMAGE, WHOAMI_IMAGE, ACME_EMAIL i APP_HOST. Wartości obrazów to pełne odwołania do przetestowanych wersji traefik, ghcr.io/tecnativa/docker-socket-proxy i traefik/whoami, najlepiej z zapisanymi digestami. Digest to skrót obliczony z zawartości, który wskazuje dokładny obraz zamiast zmiennej etykiety wersji. Nazwa hosta oznacza własną subdomenę testową, bez schematu i ścieżki. Brakujące wartości zatrzymują Compose zamiast niejawnego wyboru latest.
2. Routing z ograniczonym dostępem do API Dockera
services:
socket-proxy:
image: ${SOCKET_PROXY_IMAGE:?set tested image reference}
restart: unless-stopped
networks: [control]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CONTAINERS: "1"
EVENTS: "1"
NETWORKS: "1"
PING: "1"
VERSION: "1"
POST: "0"
traefik:
image: ${TRAEFIK_IMAGE:?set tested Traefik v3 image reference}
restart: unless-stopped
depends_on: [socket-proxy]
networks: [control, proxy]
ports: ["80:80", "443:443"]
volumes:
- ./data:/data
command:
- --providers.docker=true
- --providers.docker.endpoint=tcp://socket-proxy:2375
- --providers.docker.exposedbydefault=false
- --providers.docker.network=home_proxy
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.websecure.address=:443
- --certificatesresolvers.home.acme.email=${ACME_EMAIL:?set account email}
- --certificatesresolvers.home.acme.storage=/data/${ACME_FILE:-acme-staging.json}
- --certificatesresolvers.home.acme.caserver=${ACME_CA:-https://acme-staging-v02.api.letsencrypt.org/directory}
- --certificatesresolvers.home.acme.httpchallenge.entrypoint=web
whoami:
image: ${WHOAMI_IMAGE:?set tested whoami image reference}
restart: unless-stopped
networks: [proxy]
labels:
traefik.enable: "true"
traefik.http.routers.demo.rule: Host(`${APP_HOST:?set owned test hostname}`)
traefik.http.routers.demo.entrypoints: websecure
traefik.http.routers.demo.tls.certresolver: home
traefik.http.services.demo.loadbalancer.server.port: "80"
com.centurylinklabs.watchtower.enable: "true"
com.centurylinklabs.watchtower.scope: home-demo
networks:
control:
internal: true
proxy:
name: home_proxyTylko Traefik publikuje porty hosta. Aplikacja współdzieli z Traefikiem sieć home_proxy; wewnętrzna sieć control zawiera wyłącznie Traefika i proxy gniazda. Compose tworzy obie sieci. Stała nazwa sieci musi być unikatowa na hoście albo zmieniona zgodnie w obu miejscach.
Traefik nie otrzymuje bezpośrednio gniazda Dockera. Proxy dopuszcza wymienione endpointy odczytu i blokuje metody zapisujące przez POST=0. Odczyt nadal ujawnia metadane kontenerów, potencjalnie również zmienne środowiskowe. Samo proxy zachowuje szerokie uprawnienia do Dockera; izolacja sieci i zaufane obrazy pozostają istotne. Montowanie gniazda z :ro nie ogranicza API Dockera do odczytu.
Panel administracyjny nie jest udostępniany. HTTPS kończy się na Traefiku; połączenie Traefik–whoami korzysta z HTTP. Nie jest to szyfrowanie TLS na całej trasie. Diagnostyczna usługa whoami zwraca informacje o żądaniu i służy do krótkiego testu routingu bez danych dostępowych oraz poufnych nagłówków.
3. Test staging przed certyfikatami zaufanymi
docker compose config --quiet sprawdza złożoną konfigurację. Po kontroli podstawionych wartości polecenie docker compose up -d uruchamia środowisko testowe. docker compose logs traefik socket-proxy pomaga wykrywać problemy z odkrywaniem usług, odrzuconymi wywołaniami API i ACME. Wybrane wersje mogą wymagać dostosowania dozwolonych endpointów odczytu; ogólny dostęp do zapisu nie stanowi rozwiązania.
Domyślny adres ACME prowadzi do środowiska staging Let’s Encrypt. Przeglądarki celowo nie ufają takim certyfikatom. Po udanych testach routingu i weryfikacji domeny zmienne ACME_CA i ACME_FILE w .env otrzymują wartości https://acme-v02.api.letsencrypt.org/directory oraz acme-production.json. Polecenie docker compose up -d traefik odtwarza Traefika ze zmienioną konfiguracją. Staging i produkcja korzystają z oddzielnych plików.
Kontrola obejmuje przekierowanie HTTP, nazwę hosta HTTPS i łańcuch certyfikatów, monitoring terminu ważności oraz rzeczywiste żądanie spoza sieci domowej. Wypełniony plik JSON nie dowodzi poprawności publicznego certyfikatu. DNS, łączność, uprawnienia i limity żądań mogą uniemożliwić odnowienie. Po testach usługa diagnostyczna powinna zostać usunięta.
4. Opcjonalne monitorowanie aktualizacji
Pierwotne repozytorium containrrr/watchtower zostało zarchiwizowane 17 grudnia 2025 roku. Fork nicholas-fedor/watchtower publikuje obraz nickfedor/watchtower. Wybór wymaga odrębnej oceny utrzymania projektu i kompatybilności; znajoma nazwa obrazu nie gwarantuje bezpieczeństwa.
Opcjonalny plik monitor.yaml obserwuje wyłącznie kontenery z etykietą włączenia i zakresem home-demo. W przykładzie obie etykiety ma tylko whoami. WATCHTOWER_IMAGE musi wskazywać przetestowaną wersję. Polecenie docker compose -f compose.yaml -f monitor.yaml up -d dodaje monitor. Istniejące instancje Watchtowera na hoście również wymagają zgodnych reguł wyboru.
services:
watchtower:
image: ${WATCHTOWER_IMAGE:?set tested nickfedor/watchtower image reference}
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_MONITOR_ONLY: "true"
WATCHTOWER_LABEL_ENABLE: "true"
WATCHTOWER_SCOPE: home-demo
WATCHTOWER_POLL_INTERVAL: "86400"
WATCHTOWER_CLEANUP: "false"
WATCHTOWER_LABEL_TAKE_PRECEDENCE: "false"
WATCHTOWER_LIFECYCLE_HOOKS: "false"
labels:
com.centurylinklabs.watchtower.enable: "false"
com.centurylinklabs.watchtower.scope: home-demoTen tryb nie zastępuje kontenerów. Pobieranie obrazów pozostaje możliwe; hooki cyklu życia, czyli dodatkowe polecenia uruchamiane na określonych etapach, są jawnie wyłączone. Wyniki trafiają do logów; zewnętrzne powiadomienia wymagają oddzielnej konfiguracji i testów. Watchtower zachowuje pełny dostęp do gniazda Dockera także w trybie monitorowania. Filtr etykiet jest regułą działania, a nie granicą bezpieczeństwa.
Automatyzacja DNS-01 wymaga możliwie wąskich uprawnień API DNS lub delegowanej strefy weryfikacyjnej; nieograniczone dane dostępowe DNS nie powinny trafiać do publicznego kontenera aplikacji.
Pytania i odpowiedzi
Czy codzienna kontrola gwarantuje poprawki w ciągu 24 godzin?
Nie. Aktualizacje zależą od publikacji obrazu, śledzonego odwołania, dostępności rejestru i poprawnego wykonania. Stały digest nie śledzi nowych wydań. Tag wersji może zmieniać zawartość, ale może też przestać otrzymywać poprawki. Monitor niczego nie instaluje; wybrane odwołania do wersji wymagają świadomej aktualizacji.
Czy automatyczny restart eliminuje przerwy?
Nie. Wymiana pojedynczego kontenera przerywa działanie tej instancji. Rolling restart nie zapewnia redundancji ani strategii migracji danych. Automatyczne aktualizacje wymagają jawnego wyboru usług, sprawdzonych kontroli stanu, kopii zapasowych i procedury powrotu obejmującej obraz oraz dane. Stary obraz nie wystarczy po niekompatybilnej migracji bazy danych.
Czy lista dozwolonych IP wystarcza dla panelu administracyjnego?
Przykład nie udostępnia panelu. Późniejszy dostęp administracyjny wymaga uwierzytelniania i ograniczenia dostępu, na przykład przez VPN. Reguły IP zależą od rzeczywistego adresu źródłowego i konfiguracji zaufanych proxy; szerokie zakresy prywatne nie potwierdzają tożsamości.
Czy przebieg monitorujący wykonuje wyłącznie odczyt?
Nie. Monitor-only może pobierać obrazy, a włączone hooki mogą wykonywać polecenia. Drugi proces wewnątrz działającego aktualizatora nie zatrzymuje pierwszego procesu. --no-pull blokuje pobieranie, ale nie zastępuje trybu monitorowania.
Źródła
- Dokumentacja Docker Compose
- Dokumentacja Traefika
- Dokumentacja Let’s Encrypt
- Integracja Traefika z Dockerem: endpoint, wykrywanie usług i bezpieczeństwo API
- Traefik ACME: zapis, środowisko testowe i weryfikacja domeny
- Docker Socket Proxy: uprawnienia endpointów i izolacja
- Watchtower: pierwotne repozytorium zarchiwizowane
- Fork Watchtowera i obraz
- Watchtower: wybór etykiet i zakresu
- Watchtower: monitorowanie i pobieranie obrazów
- Watchtower: dodatkowe polecenia w cyklu działania
- Watchtower: odstęp między kontrolami
- Docker Compose: wymagane zmienne środowiskowe
- ACME: weryfikacja HTTP-01 i DNS-01
Homelab na Raspberry Pi
- Raspberry Pi 4 i 5: uruchamianie systemu z dysku SSD przez zmianę bootloadera
- UPS dla Raspberry Pi: pięć rozwiązań i kryteria wyboru
- Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń Docker Compose
- Serwer domowy Docker Compose: Traefik, TLS i monitorowanie aktualizacji
- Jellyfin na Raspberry Pi 5: Direct Play i ograniczenia transkodowania
- Raspberry Pi jako utwardzona brama WireGuard VPN ze Split-Tunnelingiem
- Monitorowanie Raspberry Pi: Prometheus i Grafana