Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dockviz-cli

A terminal dashboard for Docker problems and storage cleanup.

Go License Release Built with Bubble Tea

Korean documentation


What it is

dockviz is a live TUI for answering two operational questions:

  1. Is a container currently showing a meaningful failure signal?
  2. What is using Docker's disk space, and what can be reclaimed?

It connects directly to the Docker daemon through the official Go SDK. It does not replace Docker Engine or try to be a general-purpose Docker command wrapper.

Why use it

The Docker CLI is excellent for individual commands. dockviz is useful when you need a compact, continuously updating view of several resources at once:

  • container CPU, memory, status, ports, logs, and recent history;
  • resource summaries with current, p95, peak/trend detail, and CPU/MEM limits;
  • Compose context for services, dependencies, networks, and configured volumes;
  • actionable problems derived from Docker events;
  • image, stopped-container, volume, build-cache, and container-log usage;
  • confirmation-gated cleanup actions with the reported reclaimed space.

Validation evidence

The core cleanup/resource changes are backed by a real Docker Desktop WSL2 validation scenario, not only mocks. The latest recorded run created two 4GiB named volumes, a 768MiB test image layer, and 12 live stats containers.

Measured results from dockviz-core-20260730142414:

  • docker volume prune without --all reclaimed 0B from labelled named volumes, while docker volume prune --all reclaimed 8.59GB;
  • deleting one image tag from an 813MB multi-tag image removed only the selected tag and preserved the other tag/layers;
  • Go SDK stats collection across 12 containers improved from 19.730s sequential average to 2.058s parallel average, a 9.585x speedup;
  • Docker Desktop docker_data.vhdx remained a separate host-storage allocation, confirming why dockviz reports it separately from Docker reclaimable space;
  • a remaining 806.1MB BuildKit cache was cleaned with build-cache prune, showing why image cleanup and build-cache cleanup must stay separate.

Full report: docs/core-fixes-validation-report.ko.md

Dashboard panels

The dashboard has four panels:

Panel Purpose
Containers Live CPU/MEM, compose/project summary, p95 summaries, limits, detail, logs, and history chart
Images Local image tags and safe tag/image removal
Problems OOM/restart events, high CPU, memory pressure/growth, missing limits, and daemon disconnects
Disk Usage Docker storage breakdown and category-level prune actions

The former Networks, Events timeline, exec, container lifecycle controls, and image pull-progress screens are intentionally outside the current product scope.

Screenshots

Containers Container detail
Containers panel Container detail
Problems Images
Problems panel Images panel
Disk Usage
Disk Usage panel

Disk cleanup actions are confirmation-gated. Build cache cleanup removes only unused build-cache layers, while volume cleanup warns explicitly because unused volumes can still contain important application data.

Build Cache confirmation Local Volumes confirmation
Build Cache prune confirmation Local Volumes prune confirmation

Installation

PyPI

python -m pip install dockviz

Update an installed PyPI package with:

python -m pip install --upgrade dockviz

Debian / Ubuntu APT repository

curl -fsSL https://0206pdh.github.io/dockviz-cli/apt/dockviz-archive-keyring.asc \
  | sudo gpg --dearmor -o /usr/share/keyrings/dockviz-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/dockviz-archive-keyring.gpg] https://0206pdh.github.io/dockviz-cli/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/dockviz.list > /dev/null
sudo apt update
sudo apt install dockviz

Update it with:

sudo apt update
sudo apt install --only-upgrade dockviz

Linux / macOS release binary

curl -sL "https://github.com/0206pdh/dockviz-cli/releases/latest/download/dockviz-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')" \
  -o /usr/local/bin/dockviz
chmod +x /usr/local/bin/dockviz

Running the same command again updates the binary. There is currently no dockviz update subcommand.

Windows

Download dockviz-windows-amd64.exe or dockviz-windows-arm64.exe from the latest release.

Build from source

git clone https://github.com/0206pdh/dockviz-cli.git
cd dockviz-cli
go build -o dockviz .

To update a source checkout:

git pull
go build -o dockviz .       # Linux/macOS
go build -o dockviz.exe .   # Windows

Quick start

# Connect to the local Docker daemon
dockviz

# Load Compose context from compose.yaml/docker-compose.yml in the current directory
dockviz

# Or pass one or more Compose files explicitly
dockviz -f compose.yaml -f compose.override.yaml

# Run with simulated data; no Docker daemon is required
dockviz --demo

# Connect to a remote daemon
dockviz --host tcp://192.168.1.100:2375

# Or use DOCKER_HOST
DOCKER_HOST=tcp://192.168.1.100:2375 dockviz

# Print the build version
dockviz --version

The default path calls Docker Ping() before starting the TUI. --demo is the only mode that avoids a live daemon.

Compose context

When a Compose file is present, dockviz parses it with compose-go and overlays that configuration on top of live daemon data. It auto-discovers compose.yaml, compose.yml, docker-compose.yaml, and docker-compose.yml from the current directory. Use -f/--compose-file multiple times for explicit files.

Compose context is read-only. It is used to explain impact:

  • container detail shows service dependencies, dependents, networks, configured volumes, configured ports, and the Compose file source;
  • problem detail shows the same service blast radius before you prune, delete, restart externally, or change limits;
  • live container labels remain the primary runtime source, so dockviz still works without a Compose file.

Quantitative scenario test

To verify the live daemon path with reproducible load, run the scenario harness in scenarios/run-dockviz-performance.ps1. It creates CPU, memory, log, restart-loop, and storage-pressure workloads, writes CSV/JSON measurements, and removes only those test containers and the labelled test volume when it finishes. Keep dockviz open in another terminal while the scenario runs to correlate the numbers with the Containers, Problems, and Disk Usage panels.

For a larger disk-pressure test, use -UseMaxSafeStorage; it reserves 12 GiB by default and uses the remaining workspace-drive capacity for the payload.

powershell -ExecutionPolicy Bypass -File .\scenarios\run-dockviz-performance.ps1 `
  -RunLabel max-safe `
  -UseMaxSafeStorage `
  -StorageReserveGB 12 `
  -DurationSeconds 20 `
  -StorageReadyTimeoutSeconds 1800

For application-level Docker resource comparison, pass the same fixed workload command with -TargetImage and -TargetCommand in both runs. For focused CPU/MEM health detection, run scenarios/run-dockviz-resource-health.ps1; it creates CPU hog, memory pressure, memory growth, and no-limit containers with compose-style labels so the Containers and Problems panels can be checked directly. The full Korean guide is in docs/performance-scenarios.ko.md. An example daemon measurement is recorded in docs/performance-results.ko.md. The CPU/MEM health scenario smoke result is recorded in docs/resource-health-smoke-results.ko.md. An additional reclaim validation report, focused on unused tagged images, dangling images, unused volumes, and Docker Desktop VHDX behavior, is recorded in docs/reclaim-validation-report.ko.md. The CPU/MEM feature roadmap is documented in docs/resource-management-roadmap.ko.md.

Problems panel

The Problems panel keeps the Docker event stream internally but hides normal noise such as ordinary create and start events. It also evaluates recent CPU/MEM history from the Containers panel and, once loaded, Disk Usage storage offenders. Severity is used as an action priority:

  • OOM killed — Docker reports that the container was killed by the OOM handler;
  • Abnormal exit — a die event has a non-zero exit code;
  • Killed — the container received a kill signal;
  • Restart loop — at least three restart events occurred in ten minutes;
  • CPU saturated / High CPU / Elevated CPU — recent CPU samples stayed high enough for critical, warning, or info classification;
  • Memory over limit / Memory pressure — memory p95/current is over or near the configured memory limit;
  • Memory growth — recent memory samples trend upward materially, critical if growth is close to the limit;
  • No resource limits — a running container has neither CPU nor memory hard limits;
  • Idle memory — a container holds significant memory while CPU stays idle;
  • Noisy neighbor — one container dominates project CPU;
  • Storage offenders — large logs, build cache, unused images, stopped-container layers, unattached volumes, or Docker Desktop host-storage gap;
  • Daemon disconnected — the event stream was interrupted.

Current severity thresholds:

Signal Info Warning Critical
CPU recent average >=60% >=80% >=95%
Memory / limit >=60% >=80% >=100%
Logs reclaimable >=100 MB >=500 MB >=2 GB
Build cache reclaimable >=500 MB >=2 GB -
Unused tagged/dangling images >=100 MB >=1 GB -
Stopped container writable layers >=500 MB >=2 GB -
Unattached volumes >=100 MB >=1 GB -
Docker Desktop host-storage gap >=1 GB >=10 GB -

A later start or unpause event clears a crash/kill problem for that container. The initial event query covers the previous hour, while problem classification focuses on the recent ten-minute window. Press [Enter] on a problem to inspect its detail, current resource context, and a read-only recommendation.

Disk Usage panel

The panel uses Docker's system/df API and adds storage signals that Docker's own docker system df does not report.

Category Current action
Images Removes dangling, untagged images
Containers Removes stopped containers
Local Volumes Removes unattached local volumes; review carefully because data can be deleted
Build Cache Removes unused build-cache layers
Container Logs Truncates active log files and removes rotated siblings

On Windows Docker Desktop with the WSL2 backend, the panel also shows a read-only Host Storage section for docker_data.vhdx when it can be measured locally. This is intentionally separate from the prune table: Docker prune removes daemon-level objects, but the VHDX file can remain expanded until Docker Desktop/WSL compaction returns that allocation to Windows.

When available, dockviz also shows the part of the VHDX allocation that is outside Docker's system/df accounting. That number is a diagnostic gap, not a prune estimate.

Select a row and press d to open the confirmation dialog. The operation is performed through Docker's API for the first four categories. Container log cleanup is a local filesystem operation because Docker has no portable API for the exact on-disk log-file size.

The panel refreshes automatically every 10 seconds while it is visible; press r for an immediate refresh. 0B means Docker measured zero reclaimable bytes. N/A means the daemon returned a resource whose size or log path could not be measured. Tagged images that are unused but outside the safe dangling-image prune are shown as a separate note instead of being silently counted as reclaimable.

Do not read a large Host Storage VHDX value as Docker reclaimable space. It is the host-side virtual disk allocation, which may include free space inside the Docker Desktop VM that Docker can reuse but Windows has not reclaimed yet.

Container Logs limitations

Exact log size requires dockviz and the daemon to share a filesystem and for the process to have access to the daemon's log directory. Native Linux and a WSL distribution running dockerd directly can support this. Docker Desktop and remote DOCKER_HOST setups may report the category as unavailable or zero because the daemon's filesystem is inside another VM or host.

Do not treat an unavailable log measurement as proof that no logs exist.

Keyboard shortcuts

Key Action
q / Ctrl+C Quit
Tab Switch between Containers, Images, Problems, and Disk Usage
↑ / k Move up
↓ / j Move down
Enter Open container detail
Esc Go back or close an overlay
d Delete selected container/image, or prune the selected disk category
l Open live logs for the selected container
r Refresh data and reconnect the event stream if needed
g Open the CPU/MEM history chart

Docker connection

The live client uses DOCKER_HOST and Docker's normal environment settings. The --host flag overrides DOCKER_HOST when supplied.

The daemon must allow the current user to access its socket or endpoint. A remote TCP endpoint should be protected with appropriate TLS/network controls; an unauthenticated Docker TCP socket is equivalent to remote root access.

Architecture

main.go
  └─ cmd/root.go                 Cobra flags: --demo, --host, --version
      └─ internal/tui/start.go
          ├─ docker.NewClient()  live Docker SDK client
          ├─ docker.NewDemoClient()
          └─ Bubble Tea model
              ├─ Containers
              ├─ Images
              ├─ Problems
              └─ Disk Usage

The Docker SDK and demo implementation share the DockerClient interface, so the TUI can be tested without a daemon.

The main implementation areas are:

  • internal/docker/client.go — daemon connection and API version negotiation;
  • internal/docker/containers.go — container listing and one-shot stats;
  • internal/docker/images.go — local image listing/removal;
  • internal/docker/diskusage.go — storage accounting and cleanup actions;
  • internal/docker/events.go — lifecycle event stream;
  • internal/docker/logs.go — live log stream and Docker multiplexing;
  • internal/tui/problems.go — event-to-problem classification;
  • internal/tui/view.go and internal/tui/update.go — TUI rendering and state transitions.

Development

go test ./...
go vet ./...
go build ./...

The test suite covers the pure classification/formatting logic and demo client. Real-daemon integration tests are still a separate validation layer because Docker socket access, filesystem sharing, permissions, and available resources depend on the environment.

Release

Release automation lives in .github/workflows/release.yml. A release build is created only when a version tag such as v1.2.3 is pushed. Ordinary pushes to main do not create releases or auto-bump patch tags. The build injects the version with:

go build -ldflags="-X main.version=v1.2.3" -o dockviz .

Local builds without -ldflags report dev as their version.

License

MIT © 2026 0206pdh

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages