Monitoring beginner ⏱ 15 minutes

Dozzle: Real-Time Docker Log Viewer

Simple, lightweight log viewer for Docker containers. No database, no complexity, just logs.

By homelabbing.io • 2025-12-16
#dozzle#docker#logs#containers#lightweight

Introduction

Sometimes you don’t need a full log aggregation stack—you just need to quickly view Docker container logs in real-time with a clean, responsive interface. Dozzle provides exactly that: a lightweight, zero-configuration web interface for Docker logs.

With 5,000+ GitHub stars and millions of Docker Hub pulls, Dozzle has become the go-to tool for developers and homelab enthusiasts who want instant log visibility without the complexity of Loki or ELK. It’s perfect for troubleshooting, development, and quick production debugging.

What you’ll learn:

  • Why Dozzle complements your existing log stack
  • One-container deployment with instant access to all Docker logs
  • Multi-host monitoring with remote agents
  • Advanced filtering with regex and time ranges
  • Authentication and access control
  • Comparing Dozzle vs Loki vs docker logs CLI

Prerequisites:

  • Docker installed and running
  • Basic understanding of Docker containers
  • 50MB+ RAM available (Dozzle is tiny)
  • Optional: Multiple Docker hosts for multi-host setup

Why Dozzle?

The Docker Logging Problem

docker logs is powerful but limited:

# Good for one container
docker logs -f my-container

# But what about...
# - Viewing multiple containers simultaneously?
# - Searching across all containers?
# - Filtering by regex patterns?
# - Sharing logs with team members?
# - Mobile-friendly interface?

Dozzle solves these problems:

  • Web-based, responsive UI
  • Real-time streaming (like docker logs -f)
  • Multi-container views
  • Powerful regex filtering
  • Zero configuration required
  • Extremely lightweight (10-20MB RAM)

When to Use Dozzle

Choose Dozzle for:

  • Quick troubleshooting and development
  • Real-time container log monitoring
  • Multi-host Docker environments
  • Situations where you don’t need log retention
  • Lightweight setups where Loki is overkill
  • Teams needing shared log access

Use Loki instead when:

  • You need long-term log retention (days/weeks)
  • You want to query historical logs
  • You need log aggregation from non-Docker sources
  • You’re building observability pipelines

Use both together:

  • Dozzle for real-time debugging
  • Loki for historical analysis and alerting

Feature Comparison

FeatureDozzleLokidocker logs
Setup Complexity1 container3+ containersBuilt-in
Resource Usage10-20MB RAM500MB+ RAMN/A
Real-TimeYesYesYes (CLI only)
Historical SearchNo (session only)YesLimited
Multi-ContainerYes, beautiful UIYesCLI only
Regex FilteringYesYes (LogQL)Limited
Multi-HostYes (agents)YesNo
AuthenticationYes (optional)YesN/A
Mobile-FriendlyYesYesNo
RetentionSession onlyConfigurableDocker driver

Part 1: Quick Start Deployment

Single-Host Setup

Deploy with Docker CLI:

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

Access Dozzle:

http://localhost:8080

You’ll immediately see:

  • List of all running containers
  • Real-time log streams
  • Filter and search capabilities

Docker Compose:

version: '3.8'

services:
  dozzle:
    image: amir20/dozzle:latest
    container_name: dozzle
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: unless-stopped
    environment:
      - DOZZLE_LEVEL=info
      - DOZZLE_TAILSIZE=300
      - DOZZLE_FILTER=status=running

Start:

docker compose up -d

Part 2: Interface Overview

Main Dashboard

Container List (Left Sidebar):

  • All running containers
  • Container name and status
  • Click to view logs
  • Search bar for filtering containers

Log Viewer (Main Panel):

  • Real-time log streaming
  • Syntax highlighting
  • Timestamps
  • Auto-scroll toggle
  • Download logs button

Top Controls:

  • Search: Filter logs with regex
  • Time Range: View logs from specific period
  • Multi-Select: View logs from multiple containers
  • Settings: Customize behavior

Viewing Logs

Single container:

  1. Click container name in sidebar
  2. Logs stream in real-time
  3. Auto-scroll keeps view at bottom
  4. Click auto-scroll to freeze

Multiple containers:

  1. Click Multi-select button
  2. Select containers to view
  3. Logs merge with container labels
  4. Color-coded for easy identification

Search/Filter:

  1. Enter search term in search box
  2. Use regex: error|warn|fatal
  3. Case-insensitive by default
  4. Highlights matching terms

Keyboard Shortcuts

  • Ctrl/Cmd + K: Focus search
  • Ctrl/Cmd + Shift + K: Clear search
  • Escape: Close panels
  • Ctrl/Cmd + Shift + D: Toggle dark mode

Part 3: Advanced Filtering

Regex Patterns

Basic patterns:

# Find errors
error

# Case-insensitive errors or warnings
(?i)(error|warn|warning)

# Find HTTP 4xx or 5xx status codes
HTTP/(4|5)d{2}

# Find specific IP addresses
192.168.1.d+

# Find timestamp patterns
d{4}-d{2}-d{2}

Advanced patterns:

# Find slow queries (duration > 1000ms)
duration=([1-9]d{3,}|[1-9]d{4,})

# Find authentication failures
(auth|login|authentication).*(fail|error|denied)

# Find specific user actions
user=(admin|root).*action=(delete|modify)

# Find memory issues
(OutOfMemory|OOM|memory.*exceeded)

# Find API errors with status codes
API.*status=(4d{2}|5d{2})

Time Range Filtering

Relative time:

  • Last 5 minutes
  • Last 1 hour
  • Last 24 hours
  • Last 7 days

Absolute time:

  • Select start and end timestamps
  • View historical logs (within Docker retention)

Practical example:

  1. Container crashed at 2:15 PM
  2. Set time range: 2:00 PM - 2:30 PM
  3. Search for: error|exception|fatal
  4. Identify root cause

Part 4: Multi-Host Monitoring

Architecture

Dozzle supports two multi-host patterns:

Pattern 1: Multiple Docker Hosts

Dozzle (Main)
  ├─ Agent 1 (Docker Host 1)
  ├─ Agent 2 (Docker Host 2)
  └─ Agent 3 (Docker Host 3)

Pattern 2: Docker Swarm

Dozzle deployed as Swarm service
  → Automatically discovers all nodes
  → Shows all containers across cluster

Remote Agent Setup

On Main Dozzle Instance:

version: '3.8'

services:
  dozzle:
    image: amir20/dozzle:latest
    container_name: dozzle
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      # Enable agent mode
      - DOZZLE_REMOTE_AGENT=agent1:7007,agent2:7007,agent3:7007
    restart: unless-stopped

On Each Remote Host (agent1, agent2, agent3):

version: '3.8'

services:
  dozzle-agent:
    image: amir20/dozzle:latest
    container_name: dozzle-agent
    ports:
      - "7007:7007"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      # Run in agent mode
      - DOZZLE_MODE=agent
      - DOZZLE_AGENT_PORT=7007
    restart: unless-stopped

Verify connection:

  1. Open Dozzle main instance
  2. Click Hosts dropdown in top bar
  3. See all connected agents
  4. Select host to view its containers

Docker Swarm Deployment

Create Swarm service:

version: '3.8'

services:
  dozzle:
    image: amir20/dozzle:latest
    deploy:
      mode: global  # Deploy on every Swarm node
    ports:
      - target: 8080
        published: 8080
        mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - DOZZLE_LEVEL=info

Deploy:

docker stack deploy -c dozzle-swarm.yml monitoring

Access from any node:

http://NODE_IP:8080

Part 5: Authentication and Security

Enable Authentication

Basic authentication:

services:
  dozzle:
    image: amir20/dozzle:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      # Simple authentication
      - DOZZLE_USERNAME=admin
      - DOZZLE_PASSWORD=secure_password
    restart: unless-stopped

Access:

  1. Navigate to http://localhost:8080
  2. Enter username and password
  3. Logged in for session

Multi-User Authentication

Create users file:

# users.yml
users:
  admin:
    name: "Admin User"
    password: "$2a$10$..." # bcrypt hash
    email: [email protected]

  developer:
    name: "Developer"
    password: "$2a$10$..."
    email: [email protected]

Generate bcrypt password:

# Using htpasswd
htpasswd -nbBC 10 "" your_password | tr -d ':\n'

# Or online: https://bcrypt-generator.com/

Docker Compose with user file:

services:
  dozzle:
    image: amir20/dozzle:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./users.yml:/data/users.yml
    environment:
      - DOZZLE_AUTH_PROVIDER=simple
      - DOZZLE_USERS_FILE=/data/users.yml
    restart: unless-stopped

Reverse Proxy with HTTPS

Nginx configuration:

# /etc/nginx/sites-available/dozzle
server {
    listen 443 ssl http2;
    server_name logs.example.com;

    # SSL certificates
    ssl_certificate /etc/letsencrypt/live/logs.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/logs.example.com/privkey.pem;

    # WebSocket support (critical for real-time logs)
    location / {
        proxy_pass http://localhost: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;

        # Increase timeouts for long-lived connections
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name logs.example.com;
    return 301 https://$server_name$request_uri;
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/dozzle /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Traefik configuration:

services:
  dozzle:
    image: amir20/dozzle:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dozzle.rule=Host(`logs.example.com`)"
      - "traefik.http.routers.dozzle.entrypoints=websecure"
      - "traefik.http.routers.dozzle.tls.certresolver=letsencrypt"
      - "traefik.http.services.dozzle.loadbalancer.server.port=8080"
    restart: unless-stopped

Part 6: Configuration Options

Environment Variables

Complete configuration reference:

services:
  dozzle:
    image: amir20/dozzle:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      # Base URL (for reverse proxy)
      - DOZZLE_BASE=/logs

      # Logging level
      - DOZZLE_LEVEL=info  # Options: trace, debug, info, warn, error

      # Number of log lines to load initially
      - DOZZLE_TAILSIZE=300

      # Filter containers
      - DOZZLE_FILTER=status=running
      # or
      - DOZZLE_FILTER=name=^(app|web)

      # Authentication
      - DOZZLE_USERNAME=admin
      - DOZZLE_PASSWORD=secret

      # Enable no-analytics
      - DOZZLE_NO_ANALYTICS=true

      # Show all containers (including stopped)
      - DOZZLE_SHOW_ALL_CONTAINERS=true

      # Custom hostname
      - DOZZLE_HOSTNAME=homelab-docker

      # Remote agents
      - DOZZLE_REMOTE_AGENT=agent1:7007,agent2:7007

      # Agent mode
      - DOZZLE_MODE=agent
      - DOZZLE_AGENT_PORT=7007

      # Enable stats (container resource usage)
      - DOZZLE_ENABLE_ACTIONS=true
    restart: unless-stopped

Container Filtering

Show only specific containers:

# By name pattern
DOZZLE_FILTER=name=^(app|api|web)

# By status
DOZZLE_FILTER=status=running

# By label
DOZZLE_FILTER=label=monitoring=enabled

Label containers for Dozzle:

services:
  my-app:
    image: my-app:latest
    labels:
      - "monitoring=enabled"

Custom Branding

Change hostname displayed:

DOZZLE_HOSTNAME=Production-Server-1

Customize base path for reverse proxy:

# Access at: http://example.com/logs
DOZZLE_BASE=/logs

Part 7: Practical Use Cases

Development Workflow

Scenario: Microservices architecture with 10+ containers

Setup:

services:
  dozzle:
    image: amir20/dozzle:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - DOZZLE_FILTER=status=running

Workflow:

  1. Start all services: docker compose up -d
  2. Open Dozzle: http://localhost:8080
  3. Multi-select: API + Database + Cache
  4. Watch logs in real-time as you test
  5. Search for errors: error|exception
  6. Identify which service is failing

Production Debugging

Scenario: API responding slowly, need to debug

Steps:

  1. Open Dozzle
  2. Select API container
  3. Set time range to last 30 minutes
  4. Search: duration=[1-9]\d{3,} (requests > 1000ms)
  5. Identify slow endpoints
  6. Cross-reference with database logs

Team Collaboration

Scenario: Share logs with remote team member

Setup:

  1. Deploy Dozzle with authentication
  2. Configure reverse proxy with HTTPS
  3. Share credentials with team
  4. Team member accesses from anywhere

Benefits:

  • No VPN required (if using public domain)
  • No need to SSH into server
  • No screen sharing needed
  • Everyone sees same logs in real-time

Troubleshooting Container Crashes

Scenario: Container keeps restarting

Steps:

  1. Open Dozzle
  2. Enable Show all containers
  3. Select crashed container (will show even if stopped)
  4. View logs before crash
  5. Search: error|fatal|exception|panic
  6. Identify root cause (OOM, uncaught exception, etc.)

Part 8: Comparison and Integration

Dozzle vs Docker CLI

Docker CLI:

# View single container
docker logs -f my-container

# View last 100 lines
docker logs --tail 100 my-container

# View logs since timestamp
docker logs --since 2024-12-16T10:00:00 my-container

# Follow multiple containers (complex)
docker-compose logs -f api database cache

Dozzle equivalent:

  • Click container in UI
  • Automatically tails (like -f)
  • Select multiple containers in one view
  • Time range picker for timestamps
  • No command-line needed

When to use each:

  • Docker CLI: Automation, scripts, CI/CD pipelines
  • Dozzle: Interactive troubleshooting, team sharing

Complementing Loki

Ideal setup:

services:
  # Dozzle - Real-time viewing
  dozzle:
    image: amir20/dozzle:latest
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  # Loki - Long-term storage
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    volumes:
      - loki-data:/loki

  # Alloy - Send logs to Loki
  alloy:
    image: grafana/alloy:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./alloy-config.river:/etc/alloy/config.river

Use Dozzle for:

  • Real-time debugging (instant, no delay)
  • Quick container checks
  • Multi-container troubleshooting

Use Loki for:

  • Historical log queries (days/weeks ago)
  • Aggregated analysis across time
  • Alerting on log patterns
  • Long-term retention

Part 9: Tips and Tricks

Keyboard Navigation

Speed up workflow:

  • Ctrl+K: Quick search
  • Up/Down arrows: Navigate containers
  • Escape: Close modals
  • Click timestamp: Copy timestamp

Downloading Logs

Export logs for analysis:

  1. View container logs
  2. Click Download icon
  3. Select time range
  4. Downloads as .txt file
  5. Share with team or analyze offline

Dark Mode

Enable dark theme:

  1. Click Settings icon (gear)
  2. Toggle Dark mode
  3. Saves preference in browser

Browser Extensions

Enhance Dozzle:

  • Multi-Account Containers (Firefox): Separate Dozzle instances per environment
  • Session Buddy (Chrome): Save Dozzle tab sessions
  • Dark Reader: Force dark mode on all pages

Mobile Access

Dozzle is fully responsive:

  1. Access from phone: http://SERVER_IP:8080
  2. Add to home screen (PWA-like experience)
  3. Swipe between containers
  4. Rotate for full-width logs

Troubleshooting

Issue 1: No Containers Showing

Diagnosis:

# Check Dozzle can access Docker socket
docker logs dozzle

# Verify socket is mounted correctly
docker inspect dozzle | grep -A5 Mounts

Solution:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro  # Ensure :ro suffix

Issue 2: Logs Not Streaming

Common cause: WebSocket connection failed

Solution for reverse proxy:

# Ensure these headers are set
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

Test WebSocket:

  1. Open browser DevTools → Network
  2. Filter by WS (WebSocket)
  3. Should see 101 Switching Protocols response

Issue 3: High Memory Usage

Solution: Reduce tail size

DOZZLE_TAILSIZE=100  # Default: 300

Issue 4: Authentication Not Working

Check password hash:

# Generate new bcrypt hash
htpasswd -nbBC 10 "" your_password | tr -d ':\n'

# Ensure it starts with $2a$ or $2y$

Conclusion

Dozzle transforms Docker log viewing from a command-line chore into an elegant, interactive experience. Its simplicity, speed, and zero-configuration setup make it an essential tool for anyone running Docker containers.

Key takeaways:

  • Zero-configuration deployment in seconds
  • Beautiful, responsive web interface
  • Multi-host support with remote agents
  • Powerful regex filtering and search
  • Complements log aggregation tools like Loki

Your deployment timeline:

Today:

  1. Deploy Dozzle with one Docker command
  2. Explore the interface and container logs
  3. Try multi-container view

This week: 4. Add authentication for security 5. Configure reverse proxy with HTTPS 6. Set up remote agents for multi-host monitoring

This month: 7. Integrate with existing log aggregation (Loki) 8. Train team members on Dozzle usage 9. Create bookmarks for common log searches

Resources:

Dozzle proves that powerful tools don’t have to be complex. Sometimes the best solution is the simplest one that just works.

Happy log viewing!


Guide Version: 1.0 Last Updated: December 2024 Dozzle Version: v6.0+ Difficulty Level: Beginner Estimated Time: 20 minutes