NoctisNode
← PoradnikiSelf-hosting2026-10-239 min

Caddy jako reverse proxy dla Dockera: konfiguracja Compose z automatycznym HTTPS

Uruchom Caddy jako reverse proxy dla Dockera: jeden stos compose, wspólna sieć, reverse_proxy do nazw usług i automatyczny HTTPS — plus kiedy pomagają etykiety caddy-docker-proxy.

Krótko: uruchom Caddy we własnym kontenerze, który publikuje porty 80 i 443, podłącz go i kontenery aplikacji do jednej wspólnej sieci Dockera i skieruj `reverse_proxy` na nazwę każdej usługi i jej wewnętrzny port (na przykład `reverse_proxy app:3000`). Caddy rozwiązuje nazwę przez wbudowany DNS Dockera i automatycznie uzyskuje certyfikat TLS dla każdego adresu strony.

Ten poradnik najpierw pokazuje podejście ze zwykłym Caddyfile, potem wariant caddy-docker-proxy oparty na etykietach, i wyjaśnia, kiedy każdy z nich pasuje na pojedynczym VPS. Jeśli uruchamiasz Caddy bezpośrednio na hoście, a nie w Dockerze, zobacz podstawowy poradnik o reverse proxy w Caddy.

Jak elementy do siebie pasują

Tylko kontener Caddy publikuje porty na zewnątrz. Każdy kontener backendu dołącza do zdefiniowanej przez użytkownika sieci typu bridge (tutaj `web`) i udostępnia swój port wyłącznie w tej sieci. Wbudowany serwer DNS Dockera, dostępny w sieciach zdefiniowanych przez użytkownika, pozwala Caddy dotrzeć do `app:3000` po nazwie usługi lub kontenera, więc nigdy nie wpisujesz na sztywno adresów IP kontenerów, które zmieniają się przy każdym odtworzeniu.

Niepublikowanie portów backendów ma większe znaczenie, niż się wydaje: Docker zapisuje własne reguły iptables, więc port opublikowany przez `ports:` może być osiągalny z internetu, nawet gdy ufw twierdzi, że jest zablokowany. Dla wszystkiego, co ma stać za proxy, używaj `expose:` albo nie mapuj portów wcale.

KomponentRolaOpublikowany na hoście?
Kontener caddyKończenie TLS, routing po nazwie hosta, przekierowanie HTTP na HTTPSTak: 80/tcp, 443/tcp, 443/udp
Sieć webWspólna sieć bridge z wbudowanym DNS dla nazw usługNie
Kontenery aplikacjiTwoje usługi (aplikacje webowe, API, dashboardy)Nie, osiągalne tylko przez Caddy
Wolumen caddy_dataCertyfikaty, klucze prywatne, konto ACMENie, ale musi być trwały

Krok po kroku: zwykły Caddyfile z docker compose

  1. 01.Przed uruchomieniem Caddy skieruj rekord A (i AAAA, jeśli używasz IPv6) każdej nazwy hosta na VPS, inaczej wystawienie certyfikatu się nie powiedzie.
  2. 02.Utwórz raz wspólną sieć: `docker network create web`.
  3. 03.Utwórz `/opt/proxy/compose.yaml` i `/opt/proxy/Caddyfile` jak poniżej, a następnie uruchom `docker compose up -d` w `/opt/proxy`.
  4. 04.Podłącz każdy stos aplikacji do zewnętrznej sieci `web` i uruchom go przez `docker compose up -d`.
  5. 05.Obserwuj wystawianie pierwszego certyfikatu przez `docker compose logs -f caddy` w `/opt/proxy`.
  6. 06.Po edycji Caddyfile przeładuj bez przestoju: `docker compose exec -w /etc/caddy caddy caddy reload`.
# /opt/proxy/compose.yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"   # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data      # certificates and ACME account keys
      - caddy_config:/config
    networks:
      - web

volumes:
  caddy_data:
  caddy_config:

networks:
  web:
    external: true

Podłącz aplikację i napisz Caddyfile

Każdy stos aplikacji deklaruje tę samą sieć zewnętrzną. Nazwa usługi staje się nazwą hosta, z którą łączy się Caddy. Wolumen `caddy_data` to ten, którego nie wolno Ci stracić: jego usunięcie zmusza Caddy do ponownego zamówienia wszystkich certyfikatów, co może skończyć się przekroczeniem limitów ACME.

# /opt/app/compose.yaml
services:
  app:
    image: ghcr.io/example/app:latest
    restart: unless-stopped
    expose:
      - "3000"        # reachable on the network, NOT published on the host
    networks:
      - web

networks:
  web:
    external: true

# /opt/proxy/Caddyfile
{
	email [email protected]
}

app.example.com {
	reverse_proxy app:3000
}

grafana.example.com {
	reverse_proxy grafana:3000
}

api.example.com {
	reverse_proxy api-1:8080 api-2:8080 {
		lb_policy round_robin
		health_uri /healthz
		health_interval 10s
	}
}

Backendy w Caddy: upstreamy, load balancing i health checki

W terminologii Caddy backend to upstream dyrektywy `reverse_proxy`. W jednej dyrektywie możesz podać kilka upstreamów, wybrać `lb_policy`, np. `round_robin`, `least_conn` lub `ip_hash`, i dodać aktywne health checki przez `health_uri`, aby niedziałające kontenery wypadały z rotacji. Pasywne kontrole (`fail_duration`, `max_fails`) też się przydają, gdy aplikacja nie ma endpointu zdrowia.

Caddy domyślnie ustawia `X-Forwarded-For`, `X-Forwarded-Proto` i `X-Forwarded-Host` w przekazywanych żądaniach. Skonfiguruj aplikację tak, by ufała zakresowi sieci proxy — wtedy zobaczy prawdziwy IP klienta i będzie budować linki `https://`. WebSockety i gRPC działają przez `reverse_proxy` bez dodatkowych ustawień; dla gRPC bez szyfrowania użyj `reverse_proxy h2c://service:50051`.

Etykiety zamiast Caddyfile: caddy-docker-proxy

Osoby szukające „Caddy proxy manager” zwykle chcą tego, co oferuje Nginx Proxy Manager: dodajesz kontener i dostajesz nazwę hosta oraz certyfikat bez edycji centralnego pliku. Caddy nie ma oficjalnego GUI, ale społecznościowy projekt caddy-docker-proxy (github.com/lucaslorentz/caddy-docker-proxy) generuje Caddyfile z etykiet kontenerów i przeładowuje Caddy, gdy kontenery startują lub się zatrzymują.

Wymaga on dostępu do odczytu gniazda Dockera, co w praktyce oznacza uprawnienia roota na hoście. Montuj je tylko do odczytu, aktualizuj obraz proxy i wybierz zwykły Caddyfile, jeśli masz tylko kilka usług.

services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:ci-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - CADDY_INGRESS_NETWORKS=web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - caddy_data:/data
    networks:
      - web

  whoami:
    image: traefik/whoami
    networks:
      - web
    labels:
      caddy: whoami.example.com
      caddy.reverse_proxy: "{{upstreams 80}}"

volumes:
  caddy_data:

networks:
  web:
    external: true

Zwykły Caddyfile czy caddy-docker-proxy

Zwykły CaddyfileEtykiety caddy-docker-proxy
Konfiguracja znajduje się wJednym pliku wersjonowanym w gitEtykietach rozsianych po plikach compose
Dostęp do gniazda DockeraNiepotrzebnyWymagany (wrażliwy pod kątem bezpieczeństwa)
Nowa usługaEdytuj Caddyfile, uruchom `caddy reload`Dodaj etykiety, uruchom kontener
ObrazOficjalny `caddy:2`Obraz społecznościowy oparty na Caddy
DebugowanieCzytasz plik bezpośrednioSprawdzasz wygenerowaną konfigurację w logach
Najlepszy dlaMałych, stabilnych konfiguracji VPSWielu krótkotrwałych lub często zmienianych usług

Uruchomienie na VPS

Na VPS KVM w NoctisNode dostajesz pełny root i dedykowany IPv4, więc opublikowanie 80 i 443 z jednego kontenera Caddy i ukrycie całej reszty jest proste. Wisp (1 vCPU, 1 GB RAM) wystarczy dla Caddy i kilku lekkich kontenerów; cięższe stosy zmieszczą się na Pulse lub Umbra. Szczegóły wystawiania certyfikatów i typowe awarie opisuje jak działa automatyczny HTTPS w Caddy, a surowe przekierowanie TCP lub SSH — proxy TCP i SSH w Caddy. Zabezpiecz SSH hosta, korzystając z poradnika o hardeningu SSH.

FAQ

QJak skonfigurować Caddy jako reverse proxy do kontenera Dockera?

AUmieść Caddy i kontener w tej samej sieci Dockera zdefiniowanej przez użytkownika i użyj `reverse_proxy service-name:port` w Caddyfile. Nie używaj `localhost`, bo wewnątrz kontenera Caddy oznacza on sam Caddy.

QDlaczego Caddy zwraca 502 Bad Gateway dla mojego kontenera?

AZwykle kontenery nie są we wspólnej sieci, port jest zły (użyj wewnętrznego portu kontenera, a nie opublikowanego portu hosta) albo aplikacja nasłuchuje tylko na 127.0.0.1 wewnątrz swojego kontenera. Ustaw aplikację na 0.0.0.0 i sprawdź `docker network inspect web`.

QCzy caddy-docker-proxy jest bezpieczny?

ADziała dobrze, ale wymaga gniazda Dockera, które daje kontrolę nad hostem równoważną rootowi. Montuj je tylko do odczytu, aktualizuj obraz i nie wystawiaj endpointu administracyjnego Caddy.

QGdzie Caddy przechowuje certyfikaty w Dockerze?

AW `/data` wewnątrz oficjalnego obrazu, więc zamontuj tam nazwany wolumen. Jego utrata oznacza ponowne wystawienie wszystkich certyfikatów i możliwe przekroczenie limitów ACME.

QCzy istnieje Caddy proxy manager z interfejsem webowym?

ASam Caddy nie ma oficjalnego interfejsu webowego; konfiguruje się go przez Caddyfile, JSON lub API administracyjne. Narzędzia oparte na etykietach, takie jak caddy-docker-proxy, dają podobny przepływ pracy: dodajesz kontener i gotowe.

Caddy jako reverse proxy dla Dockera: konfiguracja Compose z automatycznym HTTPS · NoctisNode