Podman
Dozzle supports Podman through its Docker-compatible socket interface. One known difference from Docker affects setup: memory stats are often missing in rootless/Quadlet deployments (cgroup delegation). This guide covers standalone mode (local monitoring) and agent mode (remote monitoring via a central Dozzle server).
Deployment Options
| Mode | Use Case | Setup Complexity |
|---|---|---|
| Standalone | Single host log viewing | Simple |
| Agent | Multi-host centralized monitoring | Moderate |
Deployment Methods
Podman offers several launch approaches:
| Method | Auto-start | Memory Stats | Healthchecks | Best For |
|---|---|---|---|---|
| CLI | Manual | ✓ | ✓ | Development |
podman-compose | ✗ | ✓ | ✗ | Testing |
| Quadlet (systemd) | ✓ | ✗* | ✓ | Production |
*Memory stats are typically unavailable in rootless mode unless cgroup v2 memory delegation is enabled. See the FAQ at the bottom of this page.
Standalone Mode
Run Dozzle as a standalone service to monitor local Podman containers.
Rootful Setup
For system-wide Podman daemon:
# Enable and start the Podman socket
sudo systemctl enable podman.socket
sudo systemctl start podman.socket
# Dozzle can connect via the Docker socket
podman run -v /run/podman/podman.sock:/var/run/docker.sock:ro \
-p 3000:8080 \
ghcr.io/amir20/dozzle:latestRootless Setup
Rootless Podman isolates containers to a user namespace:
# Start user-level socket (runs automatically with user session)
systemctl --user enable podman.socket
systemctl --user start podman.socket
# For a user named 'appuser', Dozzle can connect via:
podman run -v /run/user/$(id -u appuser)/podman/podman.sock:/var/run/docker.sock:ro \
-p 3000:8080 \
ghcr.io/amir20/dozzle:latestImportant: A Dozzle bound to one user's rootless socket only sees that user's containers. Other users' rootless containers live in separate namespaces and won't appear.
Quadlet Deployment
Quadlet enables systemd-native container management. Create a .container file at ~/.config/containers/systemd/dozzle.container:
[Unit]
Description=Dozzle Log Viewer
After=network-online.target
Wants=network-online.target
[Container]
Image=ghcr.io/amir20/dozzle:latest
PublishPort=3000:8080
Volume=/run/user/%U/podman/podman.sock:/var/run/docker.sock:ro
HealthCmd=/dozzle healthcheck
HealthInterval=5s
HealthTimeout=10s
HealthRetries=5
HealthStartPeriod=15s
[Service]
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.targetEnable and start:
systemctl --user daemon-reload
systemctl --user enable --now dozzle.serviceFor multi-user systems, drop the same file into each user's ~/.config/containers/systemd/ and pick a distinct host port per user (e.g. PublishPort=3001:8080). Each instance only sees that user's rootless containers.
Quadlet generates a systemd timer for healthchecks. `podman-compose` does not, so healthchecks won't run on a schedule there; trigger them manually with `podman healthcheck run NAME` if needed.
Agent Mode
Run Dozzle as an agent on remote Podman hosts for centralized monitoring via a main Dozzle server. Agents communicate with the main server via gRPC.
Agent Setup
Prerequisites
- Open port 7007 on agent host
- Network connectivity between main server and agent
Start Dozzle Agent
Run Dozzle in agent mode on remote Podman hosts:
# Rootful agent
podman run -d \
--name dozzle-agent \
-v /run/podman/podman.sock:/var/run/docker.sock:ro \
-p 7007:7007 \
ghcr.io/amir20/dozzle:latest agent# Rootless agent (for user 'appuser')
sudo -u appuser podman run -d \
--name dozzle-agent \
-v /run/user/$(id -u appuser)/podman/podman.sock:/var/run/docker.sock:ro \
-p 7007:7007 \
ghcr.io/amir20/dozzle:latest agentQuadlet Agent Deployment
Create a .container file for the agent:
# dozzle-agent.container
[Unit]
Description=Dozzle Agent
After=network-online.target
Wants=network-online.target
[Container]
Image=ghcr.io/amir20/dozzle:latest
PublishPort=7007:7007
Volume=/run/user/%U/podman/podman.sock:/var/run/docker.sock:ro
Exec=agent
HealthCmd=/dozzle healthcheck
HealthInterval=5s
HealthTimeout=10s
HealthRetries=5
HealthStartPeriod=15s
[Service]
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.targetThe Dozzle image's entrypoint is `/dozzle`, so `agent` goes in `Exec=` (the command), not `Entrypoint=`.
Enable and start:
systemctl --user daemon-reload
systemctl --user enable dozzle-agent.service
systemctl --user start dozzle-agent.serviceMain Server with Remote Agents
Configure the main Dozzle server to connect to agents on remote Podman hosts.
Server Configuration
Run the main Dozzle server with agent endpoints:
podman run -d \
--name dozzle \
-p 3000:8080 \
ghcr.io/amir20/dozzle:latest \
--remote-agent "host1.example.com:7007" \
--remote-agent "host2.example.com:7007"Or with environment variables:
podman run -d \
--name dozzle \
-e DOZZLE_REMOTE_AGENT="host1.example.com:7007,host2.example.com:7007" \
-p 3000:8080 \
ghcr.io/amir20/dozzle:latestQuadlet Main Server with Agents
# dozzle-server.container
[Unit]
Description=Dozzle Server with Remote Agents
After=network-online.target
Wants=network-online.target
[Container]
Image=ghcr.io/amir20/dozzle:latest
PublishPort=3000:8080
Environment=DOZZLE_REMOTE_AGENT=host1.example.com:7007,host2.example.com:7007
HealthCmd=/dozzle healthcheck
HealthInterval=5s
HealthTimeout=10s
HealthRetries=5
HealthStartPeriod=15s
[Service]
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.target`WantedBy=multi-user.target` only applies to system units. For `systemctl --user` units, use `default.target`.
Additional Configuration
Host IDs
Nothing to set up here. Dozzle handles Podman host IDs on its own, and this section exists only because earlier versions of this page asked you to create a file that never worked.
Docker identifies an engine by the UUID in /var/lib/docker/engine-id, written once when the daemon first starts. Podman is daemonless and tracks no such identity, so its Docker-compatible /info endpoint fills that field with a fresh random UUID on every call. You can see it for yourself:
curl -s --unix-socket /run/user/$(id -u)/podman/podman.sock "http://d/v1.40/info" | jq .ID
curl -s --unix-socket /run/user/$(id -u)/podman/podman.sock "http://d/v1.40/info" | jq .IDTwo different UUIDs, and creating /var/lib/docker/engine-id changes nothing, because Podman never reads it. Dozzle instead derives a stable ID from the hostname and the container storage path, which keeps a host recognizable across restarts and keeps two rootless users on one machine apart.
If you created `/var/lib/docker/engine-id` on a Podman host following older instructions, you can delete it.
When IDs Collide
Two Podman hosts that share both a hostname and a storage path get the same derived ID, and Dozzle drops one of them as a duplicate. Hostnames are normally distinct, so this takes cloned VMs or a fleet that never set a hostname. Set DOZZLE_HOST_ID on one of them to break the tie:
# dozzle-agent.container
[Container]
Environment=DOZZLE_HOST_ID=web-01The value can be any string of letters, numbers, dashes, underscores and dots. It must be unique across your hosts and stay the same for the life of the host.
FAQ
Memory Stats Missing in Rootless Mode
Memory stats are usually missing in rootless deployments because the memory cgroup controller isn't delegated to the user slice by default. Check what's delegated:
cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/cgroup.controllersIf memory is not in the output, enable delegation via a drop-in:
sudo mkdir -p /etc/systemd/system/user@.service.d
sudo tee /etc/systemd/system/user@.service.d/delegate.conf <<'EOF'
[Service]
Delegate=cpu cpuset io memory pids
EOF
sudo systemctl daemon-reloadThen log out and back in (or reboot) for the user slice to pick up the new delegation. See the Podman rootless tutorial for details.
Healthchecks Reported as Unhealthy
podman-compose issue: Healthchecks are reported as unhealthy even though manual runs pass. This is a Podman behavior where healthchecks aren't automatically evaluated without a systemd timer (Quadlet generates one automatically).
Workaround with podman-compose:
# Manual healthcheck run
podman healthcheck run <container_id>Quadlet: HealthCmd= takes a plain command line, not the Docker CMD [...] JSON form:
HealthCmd=/dozzle healthcheckOlder podman-compose (< 1.5.0) runs all healthchecks via sh, which doesn't exist in the Dozzle image. Update to a current version.
Cross-user Container Visibility
Rootless Podman can only access containers in the same user namespace. If running Dozzle as one user, it cannot see containers from another user's rootless session.
Solution: Either run Dozzle as the same user or use rootful mode.