Deployment Guide

    Dozzle

    Real-time Docker log viewer. Monitor all your container logs from a single, lightweight web interface.

    10–15 minutes
    512MB+ RAM
    VPS

    Any KVM plan, 512MB+ RAM

    OS

    Ubuntu 22.04 / 24.04 LTS

    Starting At

    $5/month (Standard KVM)

    Introduction

    Dozzle is a lightweight, open-source, self-hosted web application for monitoring Docker container logs in real time. It connects directly to the Docker socket to stream logs instantly through a clean browser-based interface. Dozzle does not store any log files — it is designed purely for live log viewing, making it an ideal companion for developers and system administrators managing containerized workloads.

    Dozzle's container image is only ~7 MB compressed and requires minimal CPU and memory. RamNode's KVM plans starting at $4/month provide more than enough resources to run Dozzle alongside your other containers.

    Key Features

    Real-Time Log Streaming

    Instantly view logs from all running containers as they happen

    SQL Log Queries

    Analyze logs in-browser using SQL with DuckDB and WebAssembly

    Split-Screen View

    Monitor multiple containers side by side for microservice debugging

    Container Shell Access

    Attach or exec into containers directly from the browser

    Multi-Host Monitoring

    Connect to remote Docker hosts via a secure agent architecture

    Alerting & Webhooks

    Custom alert expressions with Slack, Discord, ntfy, or webhook notifications

    Docker Swarm & K8s

    Native support for Swarm clusters and Kubernetes pod logs

    JSON Log Formatting

    Automatic detection and color-coded formatting of structured JSON logs

    Part 1: Initial Server Setup

    1Connect to Your VPS

    ssh root@YOUR_SERVER_IP

    2Update the System

    apt update && apt upgrade -y

    3Install Docker

    curl -fsSL https://get.docker.com | sh

    Verify the installation:

    docker --version
    docker compose version

    Enable Docker to start on boot:

    systemctl enable docker

    For production servers, consider creating a dedicated non-root user:useradd -m dozzleadmin && usermod -aG docker dozzleadmin

    Part 2: Deploy Dozzle

    Option A — Quick Start with Docker Run

    docker run -d \
      --name dozzle \
      --restart unless-stopped \
      --volume=/var/run/docker.sock:/var/run/docker.sock:ro \
      -p 8080:8080 \
      amir20/dozzle:latest

    Access at http://YOUR_SERVER_IP:8080.

    Option B — Docker Compose (Recommended)

    mkdir -p /opt/dozzle && cd /opt/dozzle
    /opt/dozzle/docker-compose.yml
    services:
      dozzle:
        container_name: dozzle
        image: amir20/dozzle:latest
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
        ports:
          - 8080:8080
    cd /opt/dozzle
    docker compose up -d
    docker ps | grep dozzle

    The :ro flag on the Docker socket mount ensures Dozzle has read-only access — a best practice since it only needs to read container info and log streams.

    Part 3: Securing Dozzle with Authentication

    By default, Dozzle does not require authentication. For any production or internet-facing deployment, enable authentication to restrict access.

    Generate User Credentials

    docker run -it --rm amir20/dozzle generate admin \
      --password YOUR_SECURE_PASSWORD \
      --email admin@example.com \
      --name "Admin" > /opt/dozzle/users.yml

    The generated users.yml file follows this structure:

    users.yml
    users:
      admin:
        email: admin@example.com
        name: Admin
        password: $2a$11$HASHED_PASSWORD_HERE
        filter:
        roles:

    Update Docker Compose for Authentication

    /opt/dozzle/docker-compose.yml
    services:
      dozzle:
        container_name: dozzle
        image: amir20/dozzle:latest
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
          - /opt/dozzle/users.yml:/data/users.yml:ro
          - dozzle-data:/data
        ports:
          - 8080:8080
        environment:
          DOZZLE_AUTH_PROVIDER: simple
          DOZZLE_AUTH_TTL: 48h
    
    volumes:
      dozzle-data:
    cd /opt/dozzle
    docker compose down && docker compose up -d

    User Roles and Filters

    RolePermissions
    allFull access to all container actions (default)
    shellCan attach/exec into containers
    actionsCan start, stop, and restart containers
    downloadCan download container logs
    noneView logs only; no container actions

    To restrict a user to specific containers:

    Restricted user example in users.yml
    viewer:
      name: Viewer
      password: $2a$11$HASHED_PASSWORD
      filter: "label=team=frontend"
      roles: none

    Part 4: HTTPS with Nginx Reverse Proxy

    Install Nginx and Certbot

    apt install -y nginx certbot python3-certbot-nginx

    Configure Nginx

    /etc/nginx/sites-available/dozzle
    server {
        listen 80;
        server_name logs.example.com;
    
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_read_timeout 86400;
        }
    }
    ln -s /etc/nginx/sites-available/dozzle /etc/nginx/sites-enabled/
    nginx -t && systemctl reload nginx
    certbot --nginx -d logs.example.com

    The Upgrade and Connection headers are critical — Dozzle uses WebSockets for real-time log streaming. The proxy_read_timeout prevents Nginx from closing long-lived WebSocket connections.

    Restrict Dozzle to Localhost

    Once Nginx handles external traffic, bind Dozzle only to localhost:

    Update ports in docker-compose.yml
    ports:
      - 127.0.0.1:8080:8080
    docker compose down && docker compose up -d

    Part 5: Monitoring Remote Docker Hosts

    Dozzle can monitor containers across multiple Docker hosts using its agent architecture — ideal for monitoring your entire RamNode fleet from a single dashboard.

    Deploy the Agent on Remote Hosts

    docker run -d \
      --name dozzle-agent \
      --restart unless-stopped \
      -v /var/run/docker.sock:/var/run/docker.sock:ro \
      -p 7007:7007 \
      amir20/dozzle:latest agent

    The agent listens on port 7007 and communicates via gRPC.

    Connect Main Instance to Agents

    Updated docker-compose.yml
    services:
      dozzle:
        container_name: dozzle
        image: amir20/dozzle:latest
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
          - /opt/dozzle/users.yml:/data/users.yml:ro
          - dozzle-data:/data
        ports:
          - 127.0.0.1:8080:8080
        environment:
          DOZZLE_AUTH_PROVIDER: simple
          DOZZLE_AUTH_TTL: 48h
          DOZZLE_REMOTE_AGENT: agent1-ip:7007,agent2-ip:7007
    
    volumes:
      dozzle-data:

    Replace agent1-ip and agent2-ip with actual IPs of your remote VPS instances.

    Restrict agent port 7007 to only accept connections from your main Dozzle server:ufw allow from MAIN_SERVER_IP to any port 7007

    Part 6: Firewall Configuration

    ufw allow OpenSSH
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw --force enable
    ufw status verbose

    With Nginx handling traffic, only ports 80 and 443 need to be open. If running without a reverse proxy (not recommended), also allow port 8080.

    Part 7: Environment Variable Reference

    VariableDefaultDescription
    DOZZLE_ADDR:8080Address and port Dozzle listens on
    DOZZLE_BASE/Base URL path (for subpath proxies)
    DOZZLE_AUTH_PROVIDERnoneAuth mode: none, simple, or forward-proxy
    DOZZLE_AUTH_TTLsessionCookie lifetime (e.g. 48h, 720h)
    DOZZLE_FILTERGlobal container filter (e.g. label=env=production)
    DOZZLE_REMOTE_AGENTComma-separated remote agent addresses
    DOZZLE_NO_ANALYTICSfalseDisable anonymous analytics
    DOZZLE_ENABLE_ACTIONSfalseEnable start/stop/restart from UI

    Part 8: Troubleshooting

    Dozzle Shows No Containers

    Verify the Docker socket is properly mounted:

    docker exec dozzle ls -la /var/run/docker.sock

    The socket should show srw-rw---- permissions.

    WebSocket Connection Errors

    If logs aren't streaming and your browser console shows WebSocket errors, verify your reverse proxy passes the Upgrade and Connection headers correctly. See the Nginx configuration in Part 4.

    Remote Agents Not Connecting

    Check that the agent is running, port 7007 is reachable, and no firewall rules are blocking:

    # From the main Dozzle server, test connectivity:
    curl -v telnet://REMOTE_HOST_IP:7007

    High Memory Usage

    Limit Docker's log buffer size in /etc/docker/daemon.json:

    /etc/docker/daemon.json
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "3"
      }
    }
    systemctl restart docker

    Part 9: Quick Reference Commands

    ActionCommand
    Start Dozzlecd /opt/dozzle && docker compose up -d
    Stop Dozzlecd /opt/dozzle && docker compose down
    View Dozzle logsdocker logs dozzle --tail 50 -f
    Update Dozzledocker compose pull && docker compose up -d
    Restart Dozzledocker compose restart
    Generate new userdocker run -it --rm amir20/dozzle generate USERNAME --password PASS