Dozzle behind Caddy

Verified · Caddy 2.8

Config + gotchas checked against the official Dozzle docs and the issues people actually hit · 2026-06-07

A Caddy reverse-proxy setup for Dozzle, with automatic HTTPS on dozzle.example.com. Copy it, swap the domain — the gotchas that trip people up are solved below.

New to reverse proxies? Start with the Caddy + Docker guide.

Caddyfile
# Caddyfile for Dozzle
# Replace dozzle.example.com with your real domain. Caddy issues TLS automatically.

dozzle.example.com {
	reverse_proxy dozzle:8080 {
		flush_interval -1
	}
}

Replace dozzle.example.com with your domain. Your DNS A record must already point at the server.

Gotchas

What trips people up

Logs do not stream live — they arrive in bursts, or the page sits empty.

Dozzle streams logs over Server-Sent Events. Compression and response buffering break SSE. This config marks the route as streaming, so the Caddyfile omits `encode` and adds `flush_interval -1` to flush each event immediately. Do not add `encode`/`gzip` back for Dozzle.

The container shell / attach feature, or remote Dozzle agents, will not connect.

The shell uses WebSockets, which Caddy upgrades automatically. Remote agents speak gRPC — proxy those with `reverse_proxy h2c://<agent-host>:7007` (HTTP/2 cleartext), not a plain reverse_proxy.

Deploy

How to deploy

  1. Create the shared proxy network once: `docker network create proxy`.
  2. Start the stack: `docker compose up -d`.
  3. Point dozzle.example.com at the server; confirm logs stream live (no buffering) once TLS is issued.

Runnable

Full runnable stack

Dozzle + Caddy + the shared network, in one compose file — so it runs on the first try, not after you stitch the proxy in yourself. Save the Caddyfile above next to it.

docker-compose.yml (app + Caddy)
# docker-compose.yml — Dozzle + Caddy, ready to run.
# Pin caddy to a digest for production: caddy:2.8-alpine@sha256:<digest>
# 1. Save the Caddyfile above as ./Caddyfile
# 2. docker network create proxy
# 3. docker compose up -d
services:
  dozzle:
    image: docker.io/amir20/dozzle:v10.6.2@sha256:dac897ce93cbc0db48d9a6014ba24fb9438edc95c27e283a6fcc9260ea474d6d
    restart: unless-stopped
    environment:
      DOZZLE_ADDR: :8080
      DOZZLE_NO_ANALYTICS: "true"
      DOZZLE_AUTH_PROVIDER: ${DOZZLE_AUTH_PROVIDER}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - default
      - proxy
  caddy:
    image: caddy:2.8-alpine
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      - proxy
networks:
  proxy:
    external: true
volumes:
  caddy-data: {}
  caddy-config: {}

Full Dozzle stack (compose + env + docs)