Introduction

DockLog is a self-hosted Docker log viewer and admin UI. Mount the socket, open the dashboard, tail stdout/stderr.

Most observability stacks need agents, brokers, and a search cluster before you see anything. DockLog is one container on the host socket. Logs, CPU/memory stats, start/stop/restart when you need it.

Small footprint

Go 1.26 backend, Vue 3 frontend. Starts fast, usually under 30MB RAM on a VPS.

How we think about it

  • No DB required for a quick try: No-auth mode can use in-memory SQLite. Skip DB_PATH for local dashboards; add a volume when you want persistence.
  • RBAC when you need it: Wildcards and regex limit which containers each user sees.
  • Direct streaming: WebSockets from Docker. No indexing step between the container and your browser.

Docker Hub Overview

The published image is `aimldev/docklog:latest`. It ships DockLog as one self-contained container so you can start quickly without stitching together separate backend and frontend images.

Single-image deployment

One image, one container. Pull it, mount the socket, you are up.

Backend and frontend together

DockLog combines the Go backend, the Vue 3 UI, real-time streams, and configuration endpoints into the same shipped container.

RBAC and actions

Multi-user auth, container filtering, and per-user flags for start, stop, restart, delete, and shell.

Audit and persistence

When auth mode is enabled, the image stores users and audit data locally in SQLite so the deployment stays under your control.

What this page adds from the Docker Hub listing

This docs page now calls out the image name, the single-container delivery model, and the “all-in-one” deployment approach that the public image is meant to provide.

Configuration & Quickstart

Two modes: auth (SQLite for users, RBAC, audits) and no-auth (skip login; in-memory DB if you omit DB_PATH).

Option A: Auth Mode

Teams, RBAC, audit log, JWT sessions. Mount a volume for DB_PATH.

yaml
version: "3.8"
services:
  docklog:
    image: aimldev/docklog:latest
    container_name: docklog
    ports:
      - "8888:8000"
    environment:
      - SECRET_KEYSECRET_KEY: Secret token string for signing secure JWT user session cookies.=your-secure-key-here
      - DB_PATHDB_PATH: SQLite database storage file path for users and audit records.=/app/data/docklog.db
      - CLIENT_ACCESSCLIENT_ACCESS: strict or off. Controls browser origin validation for API and WebSocket access.=strict
      - ENVENV: Set to production to enforce a non-default SECRET_KEY and disable localhost origin bypass.=production
    volumes:
      - /var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.:/var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.
      - ./data:/app/data
    restart: unless-stopped

Option B: No-Auth Mode

Local dashboard with no login. In-memory DB unless you set DB_PATH.

yaml
version: "3.8"
services:
  docklog:
    image: aimldev/docklog:latest
    container_name: docklog
    ports:
      - "8888:8000"
    environment:
      - DISABLE_AUTHDISABLE_AUTH: Skips the login screen. Fine on a private LAN; don't use on the public internet.=true
    volumes:
      - /var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.:/var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.
    restart: unless-stopped

Interactive Config Builder

Use the builder tool below to configure your variables and copy the generated Compose file directly:

Docker Compose Builder

Configure your deployment settings interactively


These ALLOW_* flags are the server gate. In auth mode, each user (including admin) also needs matching can_* permissions in Admin → Users.

Generated docker-compose.yaml
yaml
version: "3.8"

services:
  docklog:
    image: aimldev/docklog:latest
    container_name: docklog
    ports:
      - "8888:8000"
    environment:
      - SECRET_KEYSECRET_KEY: Secret token string for signing secure JWT user session cookies.=generate-secret-here
      - DB_PATHDB_PATH: SQLite database storage file path for users and audit records.=/app/data/docklog.db
      - CLIENT_ACCESSCLIENT_ACCESS: strict or off. Controls browser origin validation for API and WebSocket access.=strict
      - ENVENV: Set to production to enforce a non-default SECRET_KEY and disable localhost origin bypass.=production
      - TRUST_PROXYTRUST_PROXY: Honor X-Forwarded-* headers from a trusted reverse proxy. Set true behind Nginx, Traefik, or Caddy.=true
    volumes:
      - /var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.:/var/run/docker.sockdocker.sock: Local UNIX host socket allowing direct control of the Docker daemon engine.
      - ./data:/app/data
    restart: unless-stopped

💡 Save this text into a file named docker-compose.yaml on your server, then run docker compose up -d to spin up DockLog.

Environment Reference

In auth mode, container actions are gated by per-user permissions in SQLite (can_start, can_stop, and so on). In no-auth mode, the ALLOW_* environment variables are the only gate. ALLOW_SHELL applies in both modes.

VariableDescriptionDefaultMode
DISABLE_AUTHDisable login and JWT. Also accepted as NO_AUTH=true. Forces CLIENT_ACCESS off and uses an in-memory SQLite database when DB_PATH is unset.falseBoth
SECRET_KEYJWT signing secret. Startup fails in production (ENV=production) if the default value is still in use.secret-key-change-thisAuth
DB_PATHSQLite file path. Defaults to docklog.db in auth mode and :memory: in no-auth mode when unset.docklog.dbBoth
PORTHTTP listen port inside the container.8000Both
DOCKER_HOSTDocker daemon address (standard Docker SDK variable). Defaults to the local socket.unix:///var/run/docker.sockBoth
CLIENT_ACCESSstrict or off. In strict mode, browser clients must send X-DockLog-Client: web with an allowed Origin. Native apps use JWT without Origin. Forced off when DISABLE_AUTH=true.strictAuth
ALLOWED_ORIGINSComma-separated full URLs allowed as browser origins for API and WebSocket access. Use the public HTTPS URL when behind a reverse proxy.(empty)Auth
TRUST_PROXYHonor X-Forwarded-Host and X-Forwarded-Proto from a trusted reverse proxy. Required for correct origin checks and login behind Nginx, Traefik, or Caddy.falseAuth
ENVSet to production (or GO_ENV=production) to enforce a non-default SECRET_KEY and disable localhost origin bypass.(empty)Auth
ALLOW_STARTServer gate for start actions. In auth mode, every user (including admin) also needs can_start in the database. In no-auth mode, this is the only gate.falseBoth
ALLOW_STOPServer gate for stop actions. In auth mode, every user (including admin) also needs can_stop in the database. In no-auth mode, this is the only gate.falseBoth
ALLOW_RESTARTServer gate for restart actions. In auth mode, every user (including admin) also needs can_restart in the database. In no-auth mode, this is the only gate.falseBoth
ALLOW_DELETEServer gate for remove actions. In auth mode, every user (including admin) also needs can_delete in the database. In no-auth mode, this is the only gate.falseBoth
ALLOW_SHELLServer gate for interactive shell over WebSocket. In auth mode, every user (including admin) also needs can_shell in the database. In no-auth mode, this is the only gate.falseBoth
ALLOW_BASHAlias for ALLOW_SHELL=true.falseBoth

🔒 External Exposure Warning

Running in No-Auth mode exposes container logs and telemetry metrics immediately to anyone loading the URL. If you expose this port publicly, restrict access using reverse proxy auth (like Nginx Basic Auth) or keep the service inside private/VPN subnets.

Reverse Proxy & SSL

DockLog works best behind a reverse proxy when you want HTTPS, a custom domain, or access controls in front of the app.

Nginx example

nginx
location / {
  proxy_pass http://127.0.0.1:8888;
  proxy_http_version 1.1;
  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_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
}

WebSocket support

Make sure your proxy forwards Upgrade headers so live log streaming does not drop when traffic passes through HTTPS.

HTTPS first

Put TLS termination in front of DockLog before exposing auth mode to a broader team or the public internet.

Header preservation

Keep Host, X-Forwarded-For, and X-Forwarded-Proto headers intact so logs, callbacks, and redirect behavior stay correct.

Security Hardening

Use this checklist when DockLog moves from a private lab install to a team-facing environment.

Protect the Docker socket

Only mount `docker.sock` on hosts you control, and assume the container has privileged access to the Docker daemon.

Rotate secrets regularly

Regenerate `SECRET_KEY` whenever you move the deployment or suspect it may have been exposed.

Keep auth mode private

For team use, hide the app behind VPN, SSO, or reverse-proxy auth before opening it to a wider audience.

Limit container actions

Use per-user action flags and container patterns to restrict who can restart, remove, or open shells on critical workloads.

Enable production mode

Set ENV=production, generate a unique SECRET_KEY, and keep CLIENT_ACCESS=strict so localhost origin bypass is disabled.

Lock down client access

Add trusted browser origins to ALLOWED_ORIGINS. The web UI must call the API with X-DockLog-Client: web.

Permissions & Client Access

DockLog separates who can see a container from who can act on it. Both checks must pass before an action is allowed.

Visibility

Controlled by each user's allowed_containers patterns. Admins see everything. Staff members only see containers that match at least one assigned pattern.

Actions

Auth mode uses database flags: can_start, can_stop, can_restart, can_delete, and can_shell. No-auth mode uses the matching ALLOW_* environment variables instead.

JWT sessions last 24 hours. When a password changes, password_version increments and existing tokens return SESSION_INVALIDATED. Admins can also deactivate accounts, which returns ACCOUNT_DEACTIVATED.

Login attempts are rate-limited to 10 failures per IP every 15 minutes. The public GET /api/config endpoint exposes auth mode and current ALLOW_* flags without a token.

WebSocket auth accepts either an Authorization: Bearer header or the browser subprotocol Sec-WebSocket-Protocol: docklog-auth, <token>.

Forgotten Password Recovery

DockLog stores credentials only in your local SQLite file. Use the built-in reset-password command instead of opening the database with sqlite3 while the app is running — the server holds a write lock on the DB, and the runtime image does not ship the SQLite CLI.

Host terminal access required

You need shell access on the Docker host. The new password must be at least 8 characters. Existing JWT sessions are invalidated automatically.

Interactive CLI Autocomplete Sandbox
Press TAB to complete
# Start typing commands like `docker ps` or `docker compose` to try the auto-suggestion.
$
Try typing docker ps and hit the TAB key to autocomplete instantly.

Recommended: built-in reset command

From the host, run this inside the running container (replace docklog with your container name and quote the password):

bash
docker exec docklog ./docklog reset-password admin 'YourNewPassword123'

The command uses the same DB_PATH as the running service (default /app/data/docklog.db). On first login after reset, DockLog will prompt for a password change because password_changed is cleared.

If the database is locked

When the reset command reports a locked database, stop the app first, run a one-off container against the same data volume, then start again:

bash
docker compose stop docklog
docker compose run --rm \
  -e DB_PATHDB_PATH: SQLite database storage file path for users and audit records.=/app/data/docklog.db \
  docklog ./docklog reset-password admin 'YourNewPassword123'
docker compose start docklog

Alternative: re-seed the database

If you do not need existing users or audit history, stop the container, delete ./data/docklog.db on the host, and start again. DockLog seeds admin / admin123 on first boot.

Troubleshooting

These are the most common issues teams run into during first deploys and proxy-based setups.

Blank logs or no live updates

Confirm the Docker socket is mounted, verify the target containers are running, and make sure your proxy forwards WebSocket Upgrade headers.

Permission denied on actions

In auth mode, check the user's can_* flags and allowed_containers patterns. In no-auth mode, confirm the matching ALLOW_* environment variable is set to true.

API blocked from browser or curl

With CLIENT_ACCESS=strict, browser clients need X-DockLog-Client: web and an allowed Origin. Add extra origins to ALLOWED_ORIGINS or use CLIENT_ACCESS=off only for local debugging.

Backup & Upgrade

DockLog keeps important state in the mapped data directory when auth mode is enabled. Back up that folder before upgrading or migrating hosts.

Backup the data directory

Archive `./data` regularly so your SQLite database, users, and audit records can be restored quickly after a migration.

Upgrade the image

Pull the latest image tag, recreate the container, and keep the persistent volume or host folder attached.

Typical upgrade flow

bash
docker pull aimldev/docklog:latest
docker compose up -d --force-recreate

Restore tip

If you use the default `DB_PATH`, restoring the SQLite file into the same mapped volume is usually enough to bring users and settings back online.

RBAC Rules & Regex Permissions

On a shared host, you usually do not want every developer seeing every container. Assign allowed_containers patterns per user: exact names, wildcards, or full regex.

Pattern Matching Strategies

1. Exact name match

A plain string like redis is anchored automatically and matches only a container named exactly redis.

2. Wildcard matching

Asterisks are converted to regex wildcards. For example, backend-* matches backend-api and backend-worker, while *redis* matches any name containing redis.

3. Full regular expressions

Patterns that already include ^ or $ are treated as raw regex. For example, ^prod-.*-app$ limits visibility to names that start with prod- and end with -app.

Assigning Multiple Rules

You can assign multiple container filters to a single staff member's profile. Separate individual matching rules with a comma (e.g. backend-*, *web-server, ^nginx-prod$). The user will be able to see containers matching any of the specified rules.

Architecture Overview

Go backend talks to Docker. Vue frontend in the same image. SQLite on disk when auth mode has a DB_PATH volume.

Go backend

Handles Docker API access, container control actions, RBAC checks, and server-side orchestration.

Vue 3 frontend

Presents the log viewer, metrics, login flows, and admin tools in a responsive glassmorphic interface.

SQLite persistence

Stores users, passwords, and audits locally so the deployment stays portable and under your control.

WebSocket streaming

Streams logs, host stats, Docker events, and optional shell sessions over WebSockets with JWT subprotocol support in browsers.

Historical CPU and memory samples are stored in SQLite for up to 30 days, then pruned automatically. Host metrics cover CPU, memory, total memory, and core count.

Product Tour

Screenshots from a live instance. Same UI you get after mounting the Docker socket and signing in.

DockLog dashboard showing host CPU and memory metrics

Dashboard

Host CPU and memory at the top. Container list with status, uptime, and quick actions.

DockLog container view with live log stream

Logs and container actions

Live stdout/stderr with search, autoscroll, and start/stop/restart/remove when your permissions allow it.

DockLog RBAC settings for a staff user

RBAC

Per-user container patterns and action flags. Wildcards like backend-* or regex when you need tighter control.

DockLog audit log listing user and container events

Audit log

Logins, container actions, shell use, and admin changes stored in SQLite when auth mode has a persistent DB_PATH.

Future Roadmap

Log viewer today. Multi-host, K8s, alerts, and the rest are planned but not shipped. The list below is direction, not a release schedule.

  • Multi-host · Switch between Docker daemons from one UI. Today: one daemon per instance via DOCKER_HOST.
  • Kubernetes · Pod logs and workload views without the Docker socket.
  • Alerts · Notify on log patterns, container exits, or resource spikes (Slack, email, webhooks).
  • Compose stacks · Deploy and update Compose projects from the UI, not just watch containers they already started.
  • Richer metrics · Disk and network stats, longer retention. CPU and memory only for now.

Track or discuss ideas on GitHub Issues.