Agent Mode
Docker OnlyDozzle can run in agent mode which can expose Docker hosts to other Dozzle instances. All communication is done over a secured connection using TLS. This means that you can deploy Dozzle on a remote host and connect to it from your local machine.
An agent is only as private as the network it listens on
The certificate Dozzle ships with is the same in every copy of the image, so it encrypts the connection but it does not prove who is on the other end. Anyone who can reach port 7007 can connect their own Dozzle to your agent, read every log on that host and run commands inside its containers. The agent does not look at DOZZLE_ENABLE_SHELL or DOZZLE_ENABLE_ACTIONS, those flags only control what the UI offers.
Keep port 7007 on a private network, and if the agent is reachable from anywhere else, generate your own certificate so agents only accept your hub.
Using Docker Swarm?
If you are using Docker Swarm Mode, you don't need to use agents. Dozzle will automatically discover itself and create a cluster using swarm mode. See Swarm Mode for more information.
How to Create an Agent
To create a Dozzle agent, you need to run Dozzle with the agent subcommand. Here is an example:
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agentservices:
dozzle-agent:
image: amir20/dozzle:latest
command: agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 7007:7007Docker Socket Proxy users
If you are using a remote agent you CANNOT add a socket proxy on top of the agent. Dozzle agents REPLACE using a proxy, see Remote Hosts for more info and how to use a socket proxy instead of an agent.
The agent will start and listen on port 7007. You can connect to the agent using the Dozzle UI by providing the agent's IP address and port. The agent will only show the containers that are available on the host where the agent is running.
TIP
You don't need to expose port 7007 if using Docker network. The agent will be available to other containers on the same network. This is the safest way to run an agent, since nothing outside that network can reach it.
How to Connect to an Agent
To connect to an agent, you need to provide the agent's IP address and port. Here is an example:
docker run -p 8080:8080 amir20/dozzle:latest --remote-agent agent:7007services:
dozzle:
image: amir20/dozzle:latest
environment:
- DOZZLE_REMOTE_AGENT=agent:7007
ports:
- 8080:8080 # Dozzle UI portNote that it is not necessary to mount the local Docker socket when connecting to agents, in which case the UI will only show the containers that are available on the agents.
TIP
If you want to include the host containers in the UI as well, mount the docker.sock socket as shown in the getting started example.
TIP
You can connect to multiple agents by providing multiple DOZZLE_REMOTE_AGENT environment variables. For example, DOZZLE_REMOTE_AGENT=agent1:7007,agent2:7007.
TIP
In server mode you can also add an agent from the UI, with Add host at the bottom of the host list or the Hosts step of the setup wizard. Dozzle connects to the agent before saving it, and the host shows up without a restart. Agents added this way are saved in /data/dozzle.yml, so /data has to be on a volume. Agents set with DOZZLE_REMOTE_AGENT stay as they are and can't be removed from the UI.
Host Groups
When managing many agents across different environments, you can assign each agent to a named group. Groups appear as collapsible sections in the sidebar, and each group has a "merge all" button to view combined logs from every host in the group.
The connection string format is endpoint|name|group — all three parts are optional:
| Format | Result |
|---|---|
agent:7007 | No name override, no group |
agent:7007|web-1 | Name override, no group |
agent:7007|web-1|Production | Name override + group |
agent:7007||Production | Default hostname + group |
docker run -p 8080:8080 amir20/dozzle:latest \
--remote-agent agent1:7007|web-1|Production \
--remote-agent agent2:7007|web-2|Production \
--remote-agent agent3:7007|dev-1|Developmentservices:
dozzle:
image: amir20/dozzle:latest
environment:
- DOZZLE_REMOTE_AGENT=agent1:7007|web-1|Production,agent2:7007|web-2|Production,agent3:7007|dev-1|Development
ports:
- 8080:8080The sidebar will display:
▾ Production
web-1
web-2
▾ Development
dev-1
ungrouped-host ← agents without a group appear belowClicking the merge icon next to a group name opens a combined log view streaming from all hosts in that group. The merged view is also available directly at /host-group/<group-name>.
Agents without a group continue to work exactly as before and appear below grouped sections.
Common Issues
Agent Not Showing Up
If you are seeing An agent with an existing ID was found. Removing the duplicate host. then you have two hosts that use the same Server ID.
Dozzle utilizes the Docker API to collect information about hosts. Each agent requires a unique host ID that remains consistent across restarts to ensure proper identification. Currently, agents identify the host using either Docker's system ID or node ID.
If you are operating in a Swarm environment, the node ID will be employed for this purpose. However, if you notice that not all hosts are visible, it may be due to the presence of duplicate hosts configured with the same host ID.
To resolve this issue, you should remove /var/lib/docker/engine-id from your system and restart. This action will help eliminate any conflicts caused by duplicate host IDs. For additional information and troubleshooting tips, please refer to the FAQ.
Advanced Options
Setting Up Healthcheck
You can set a healthcheck for the agent, similar to the healthcheck for the main Dozzle instance. When running in agent mode, healthcheck checks agent connection to Docker. If Docker is not reachable, the agent will be marked as unhealthy and will not be shown in the UI.
To set up healthcheck, use the healthcheck subcommand. Here is an example:
services:
dozzle-agent:
image: amir20/dozzle:latest
command: agent
healthcheck:
test: ["CMD", "/dozzle", "healthcheck"]
interval: 5s
retries: 5
start_period: 5s
start_interval: 5s
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 7007:7007Changing Agent's Name
Similar to Dozzle instance, you can change the agent's name by providing the DOZZLE_HOSTNAME environment variable. Here is an example:
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agent --hostname my-special-nameservices:
dozzle-agent:
image: amir20/dozzle:latest
command: agent
environment:
- DOZZLE_HOSTNAME=my-special-name
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 7007:7007This will change the agent's name to my-special-name and will be reflected on the UI when connecting to the agent.
Setting Up Filters
You can set up filters for the agent to limit the containers it can access. These filters are passed directly to Docker, restricting what Dozzle can view.
services:
dozzle-agent:
image: amir20/dozzle:latest
command: agent
environment:
- DOZZLE_FILTER=label=color
volumes:
- /var/run/docker.sock:/var/run/docker.sock:roThis will restrict the agent to displaying only containers with the label color. Keep in mind that these filters are combined with the UI filters to narrow down the containers. To learn more about the different types of filters, read the filters documentation.
Custom Certificates
Dozzle ships with a self-signed certificate that both ends present to each other, and each end trusts that one certificate and nothing else. It is compiled into the binary, so it is identical in every Dozzle install and anyone can read it out of the public image.
That means it gives you encryption but no authentication. An agent cannot tell your hub apart from someone else's, so the only thing keeping strangers out of an agent started with the defaults is that they cannot reach port 7007.
When you need your own certificate
If port 7007 is reachable by anything you do not control, which includes publishing it on a host with a public IP, generate your own pair. Every deployment that does gets a credential nobody else holds.
Run generate-certs to write a unique pair:
docker run --rm -v "$PWD":/out amir20/dozzle:latest generate-certs --cert-out /out/dozzle_cert.pem --key-out /out/dozzle_key.pemCopy both files to the hub and to every agent. Dozzle looks for them at /dozzle_cert.pem and /dozzle_key.pem, so mounting them there is enough. You can put them elsewhere with the --cert and --key flags or the DOZZLE_CERT and DOZZLE_KEY environment variables.
Treat the key like a password. Anyone holding it can connect to your agents, and an agent will reject a hub presenting anything else, so the hub and its agents have to be given the same pair and restarted together.
Here is an example using the default paths:
services:
agent:
image: amir20/dozzle:latest
command: agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets:
- source: cert
target: /dozzle_cert.pem
- source: key
target: /dozzle_key.pem
ports:
- 7007:7007
secrets:
cert:
file: ./cert.pem
key:
file: ./key.pemOr using custom paths with environment variables:
services:
agent:
image: amir20/dozzle:latest
command: agent
environment:
- DOZZLE_CERT=/certs/my-cert.pem
- DOZZLE_KEY=/certs/my-key.pem
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./certs:/certs
ports:
- 7007:7007Or using command-line flags:
docker run -v /var/run/docker.sock:/var/run/docker.sock -v ./certs:/certs -p 7007:7007 amir20/dozzle:latest agent --cert /certs/my-cert.pem --key /certs/my-key.pemservices:
agent:
image: amir20/dozzle:latest
command: agent --cert /certs/my-cert.pem --key /certs/my-key.pem
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./certs:/certs
ports:
- 7007:7007TIP
Docker secrets are preferred for providing certificates. They can be created using docker secret create command or as the example above using docker-compose.yml. The same certificates should be provided to the Dozzle instance connecting to the agent.
This will mount the certificate and key files to the agent. The agent will use these certificates for communication. The same certificates should be provided to the Dozzle instance connecting to the agent.
If you would rather generate them with openssl than with generate-certs:
$ openssl genpkey -algorithm Ed25519 -out key.pem
$ openssl req -new -key key.pem -out request.csr -subj "/C=US/ST=California/L=San Francisco/O=My Company"
$ openssl x509 -req -in request.csr -signkey key.pem -out cert.pem -days 365Private certificate for agents added from the UI
When you add an agent with Add host, the dialog has a Private certificate toggle. It is on by default for new hosts. With it on, only this Dozzle can connect to the agent, even if port 7007 is reachable by others.
The first time it is used, Dozzle creates its own pair in /data/agent_cert.pem and /data/agent_key.pem. The pair is never replaced, so every private agent keeps working across restarts and updates. The compose snippet in the dialog passes the pair to the agent through DOZZLE_CERT_PEM and DOZZLE_KEY_PEM:
services:
dozzle-agent:
image: amir20/dozzle:vX.Y.Z # same tag as your Dozzle
command: agent
environment:
DOZZLE_CERT_PEM: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
DOZZLE_KEY_PEM: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 7007:7007The snippet contains the private key, so treat it like a password. The toggle is per host: agents that already exist, and any agent added with the toggle off, keep using the certificate they have. Dozzle records which agents are private under privateAgents in /data/dozzle.yml. The toggle is not offered when Dozzle already runs a custom certificate, because every agent needs that pair anyway. The snippet uses the same image as your Dozzle. An older agent ignores DOZZLE_CERT_PEM and DOZZLE_KEY_PEM, presents the built-in certificate, and is refused.
Comparing Agents with Remote Connection
Agents are similar to remote connections, but they have some advantages. Generally, agents are preferred over remote connections due to performance and security reasons. Here is a comparison:
| Feature | Agent | Remote Connection |
|---|---|---|
| Performance | Better with distributed load | Worse on the UI |
| Security | Encrypted, bring your own cert | Insecure or Docker TLS |
| Ease of use | Easy out of the box | Requires exposing Docker socket |
| Permissions | Full access to Docker | Can be controlled with a proxy |
| Reconnect | Automatically reconnects | Requires UI restart |
| Healthcheck | Built-in healthcheck | No healthcheck |
| Filters | Supports filters | No support for filters |
If you do plan to use remote connections, make sure to secure the connection using Docker TLS or a reverse proxy.