Forward Proxy
Dozzle can be configured to read proxy headers by setting --auth-provider to forward-proxy.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/dozzle/data:/data -p 8080:8080 amir20/dozzle --auth-provider forward-proxyservices:
dozzle:
image: amir20/dozzle:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /path/to/dozzle/data:/data
ports:
- 8080:8080
environment:
DOZZLE_AUTH_PROVIDER: forward-proxyMount /data here as well. Per-user settings are written to disk in forward-proxy mode too, and without the volume they are lost every time the container is recreated.
In this mode, Dozzle expects the following headers:
Remote-Userto map to the username e.g.johndoeRemote-Emailto map to the user's email address. This email is also used to find the right Gravatar for the user.Remote-Nameto be a display name likeJohn DoeRemote-Filterto be a comma-separated list of filters allowed for user.Remote-Rolesto be a comma-separated list of roles allowed for user.
Additionally, you can configure a logout URL with:
DOZZLE_AUTH_LOGOUT_URL: http://oauth2.example.ru/oauth2/sign_outSetting up Dozzle with Authelia
Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management. While setting up Authelia is out of scope for this section, the configuration can be shared as an example for setting up Dozzle with Authelia.
➡️ Click to expand Authelia example
networks:
net:
driver: bridge
services:
authelia:
image: authelia/authelia
container_name: authelia
volumes:
- ./authelia:/config
networks:
- net
labels:
- "traefik.enable=true"
- "traefik.http.routers.authelia.rule=Host(`authelia.example.com`)"
- "traefik.http.routers.authelia.entrypoints=https"
- "traefik.http.routers.authelia.tls=true"
- "traefik.http.routers.authelia.tls.options=default"
- "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth"
- "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
- "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
expose:
- 9091
restart: unless-stopped
traefik:
image: traefik:v3.5
container_name: traefik
volumes:
- ./traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock
networks:
- net
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.api.entrypoints=https"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.tls=true"
- "traefik.http.routers.api.tls.options=default"
- "traefik.http.routers.api.middlewares=authelia@docker"
ports:
- "80:80"
- "443:443"
command:
- "--api"
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
- "--providers.file.filename=/etc/traefik/certificates.yml"
- "--entrypoints.http=true"
- "--entrypoints.http.address=:80"
- "--entrypoints.http.http.redirections.entrypoint.to=https"
- "--entrypoints.http.http.redirections.entrypoint.scheme=https"
- "--entrypoints.https=true"
- "--entrypoints.https.address=:443"
- "--log=true"
- "--log.level=DEBUG"
dozzle:
image: amir20/dozzle:latest
networks:
- net
environment:
DOZZLE_AUTH_PROVIDER: forward-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- dozzle:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.dozzle.rule=Host(`dozzle.example.com`)"
- "traefik.http.routers.dozzle.entrypoints=https"
- "traefik.http.routers.dozzle.tls=true"
- "traefik.http.routers.dozzle.tls.options=default"
- "traefik.http.routers.dozzle.middlewares=authelia@docker"
expose:
- 8080
restart: unless-stopped
volumes:
dozzle:###############################################################
# Authelia configuration #
###############################################################
server:
address: tcp://0.0.0.0:9091
log:
level: info
totp:
issuer: authelia.com
identity_validation:
reset_password:
jwt_secret: a_very_important_secret
authentication_backend:
file:
path: /config/users_database.yml
access_control:
default_policy: deny
rules:
- domain: traefik.example.com
policy: one_factor
- domain: dozzle.example.com
policy: one_factor
session:
secret: unsecure_session_secret
cookies:
- domain: example.com # Should match whatever your root protected domain is
authelia_url: https://authelia.example.com
default_redirection_url: https://public.example.com
regulation:
max_retries: 3
find_time: 120
ban_time: 300
storage:
encryption_key: you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this
local:
path: /config/db.sqlite3
notifier:
filesystem:
filename: /config/notification.txtValid SSL keys are required because Authelia only supports SSL.
Authelia sends group membership in Remote-Groups, and Dozzle does not read that header by default. To map Authelia groups onto Dozzle roles, set DOZZLE_AUTH_HEADER_ROLES: Remote-Groups on the Dozzle service and name the groups after the roles. The dozzle_ prefixed aliases exist for this, so a group called dozzle_shell grants the shell role and other group names are ignored. Without that mapping every authenticated user gets all roles.
Setting up Dozzle with Cloudflare Zero Trust
Cloudflare Zero Trust is a service for authenticated access to self-hosted software. This section defines how Dozzle can be set up to use Cloudflare Zero Trust for authentication.
services:
dozzle:
image: amir20/dozzle:latest
environment:
DOZZLE_AUTH_PROVIDER: forward-proxy
DOZZLE_AUTH_HEADER_USER: Cf-Access-Authenticated-User-Email
DOZZLE_AUTH_HEADER_EMAIL: Cf-Access-Authenticated-User-Email
DOZZLE_AUTH_HEADER_NAME: Cf-Access-Authenticated-User-Email
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- dozzle:/data
expose:
- 8080
restart: unless-stopped
volumes:
dozzle:expose keeps port 8080 off the host, so the only way in is through the tunnel. Publishing it with ports would let anyone on the host set Cf-Access-Authenticated-User-Email themselves and skip Cloudflare entirely.
After running the Dozzle container, configure the Application in Cloudflare Zero Trust dashboard by following the guide.
Setting up Dozzle with Pocket ID
TIP
Dozzle speaks OpenID Connect natively now, so you can point --auth-oidc-issuer straight at Pocket ID and skip oauth2-proxy entirely. See Sign in with GitHub & OIDC. The recipe below is still here for setups that already run oauth2-proxy or want the proxy to guard more than Dozzle.
You must first setup a container to pass OpenID Connect authentication through your reverse proxy.
Below is an example using oauth2-proxy.
➡️ Click to expand oauth2-proxy example
Create a new OIDC client in Pocket ID for Dozzle:
- Name:
Dozzle - Callback URLs:
https://dozzle.example.com/oauth2/callback - PKCE:
Enabled
Copy the Client ID and Client Secret values for use later.
- Name:
Add the following to your existing Dozzle compose:
ymlenvironment: DOZZLE_AUTH_PROVIDER: forward-proxy DOZZLE_AUTH_HEADER_USER: X-Forwarded-User DOZZLE_AUTH_HEADER_EMAIL: X-Forwarded-Email DOZZLE_AUTH_HEADER_NAME: X-Forwarded-Preferred-UsernameComment out the Dozzle ports, as we will redirect these through the new authentication container.
This method should not require any changes to your reverse proxy configuration.
yml# ports: # - 8080:8080Add a new oauth2-proxy container service to your existing Dozzle compose:
ymlservices: # ... oauth2-proxy: image: quay.io/oauth2-proxy/oauth2-proxy:latest restart: unless-stopped container_name: dozzle-oidc command: --config /oauth2-proxy.cfg volumes: - "./oauth2-proxy.cfg:/oauth2-proxy.cfg" ports: - 8080:4180Create the oauth2-proxy config file.
In the directory beside your compose file, create
oauth2-proxy.cfg:tomlclient_id = "xxx" # from Pocket ID client_secret = "xxx" # from Pocket ID cookie_secret = "xxx" # generate with openssl rand -base64 32 | tr -- '+/' '-_' upstreams = "http://dozzle:8080" # upstream to Dozzle containers internal port code_challenge_method = "S256" # PKCE challenges plain or S256 cookie_expire = "0" # seconds, 0 for session cookie_name = "__Host-oauth2-proxy" # or __Secure-oauth2-proxy (less secure) cookie_secure = true # uses the secure HTTPS cookie email_domains = ["*"] # allows any email domain to authenticate http_address = "0.0.0.0:4180" # port oauth2-proxy listens on oidc_issuer_url = "https://id.example.com" # your Pocket base URL provider_display_name = "Pocket ID" # display name for OIDC login provider = "oidc" # use OpenID connect reverse_proxy = true # reverse proxy the traffic scope = "openid email profile groups" # passthru these OIDC scopesFill in the variables per the comments.
Finally - restart your Docker compose stack.
Your reverse proxy should now authenticate you to Dozzle via oauth2-proxy.
Check logs for troubleshooting.