π« The 2:00 AM SSH Nightmare
Every sysadmin, DevOps engineer, and backend developer knows this drill by heart:
Your monitoring ping rings. A production or staging server is sluggish. You SSH into the remote machine, open your shell, and start typing the ritual sequence of 15 commands:
docker ps -a
docker stats --no-stream
docker inspect --format='{{.State.ExitCode}}' <container>
docker logs --tail 50 <container>
docker system df
df -h
free -m
uptime
cat docker-compose.yml
You cross-reference logs, parse memory cgroups, try to decipher whether an Exit Code 137 was an actual Linux OOM Killer invocation or a manual SIGKILL, and hunt down why your /var/lib/docker partition climbed from 55% to 89% in two weeks.
Web dashboards like Portainer exist, but they are heavy web apps that require exposing extra ports, configuring web servers, and opening remote ports. CLI tools like LazyDocker are great, but they are mostly passive viewersβthey display tables, but donβt tell you:
"I detected 6 issues on this host: here are the 3 you must fix right now, why they happened, and how to fix them in one click."
That is why I created Dockeretior.
β What is Dockeretior?
Dockeretior is an interactive, zero-overhead Terminal UI (TUI) and latent pseudo-terminal (PTY) supervisor written in Go.
It runs directly in your terminal over SSH or local bash, featuring:
- Split-Screen Dashboard: A live container list on the left alongside 4 real-time ASCII metric gauges on the right (CPU load & sparkline trends, RAM vs host cgroups, Network RX/TX throughput, Block I/O, PIDs, and uptime).
- π©Ί AutoDoctor (Intelligent Root-Cause Diagnostics): A health diagnostic engine that correlates Exit Codes, OOM Killer cgroups, binary entrypoint failures (126/127), restart loops, and security exposures into a Server Health Score (0 - 100) and a prioritized Top 3 Remediation Plan.
-
π Visual Docker Compose Topology: Automatically parses multi-service Compose files and draws an ASCII dependency tree mapping services,
depends_ondirected graphs, volumes, and networks. - π‘ 1-Click Storage Reclaim: Identifies dangling images, orphaned volumes, and build cache (often 30+ GB of hidden reclaimable disk), letting you free it with a single keystroke (c).
- π¨ Alert Dispatcher & Drift Tracking: Sends structured alerts to Slack, Discord, or Telegram, and tracks historical memory and disk creep across snapshots.
-
β‘ Latent PTY Supervisor (Hot-Toggle): Can run completely invisible in the background of your SSH shell, toggled into view in milliseconds using
Ctrl + \orCmd + Option + Space.
π©Ί The Heart of Dockeretior: AutoDoctor
Instead of drowning the user in data, Dockeretior prioritizes actionable intelligence.
When you run ./bin/dockeretior --doctor or press a inside the TUI, AutoDoctor inspects your host in sub-second time and outputs:
================================================================================
π©Ί AUTODOCTOR - SERVER HEALTH REPORT
================================================================================
Health Score : 58/100 π΄ Critical
Containers : 3 running, 1 stopped (4 total)
Generated : 2026-10-01 14:17:01
--------------------------------------------------------------------------------
SUBSYSTEMS STATUS:
π’ Docker Engine : Docker v29.8.1, 16 CPUs, 31.3 GB RAM.
π’ Containers : 3 active, 1 stopped.
π΄ Storage : 29.88 GB reclaimable in cache and unused images.
π‘ Security : 3 security alerts identified.
--------------------------------------------------------------------------------
TOP 3 PRIORITIZED ACTIONS:
1. [π΄ CRITICAL] Significant Reclaimable Storage in Docker (29.88 GB) (Docker Storage)
β³ Root Cause: Accumulation of 14 dangling images, 11 orphaned volumes, and build cache.
β³ Solution : Press 'c' inside AutoDoctor to reclaim disk space immediately.
β³ Command : docker system prune -a --volumes
2. [π΄ CRITICAL] Container 'buildkit_builder' running in privileged mode (--privileged)
β³ Root Cause: Privileged mode enabled, bypassing standard Docker container isolation.
β³ Solution : Remove 'privileged: true' and grant only required Linux capabilities ('cap_add').
3. [π‘ WARNING] PostgreSQL port exposed on 0.0.0.0 (5432:5432) on 'app-postgres'
β³ Root Cause: Public interface binding allows external connections from any IP.
β³ Solution : Bind to '127.0.0.1:5432:5432' or rely on internal Docker bridge networks.
--------------------------------------------------------------------------------
π‘ RECLAIMABLE DISK: 29.88 GB accumulated in unused images and build cache.
To free space: launch dockeretior (press 'a' then 'c') or run docker system prune -a --volumes.
================================================================================
Automatic Correlation of Crash Loops
When a container dies or starts restarting, AutoDoctor doesn't just show a red icon:
-
Exit Code 137: Correlates whether the kernel invoked the OOM Killer and compares current RAM usage against the container's hard cgroup limit (e.g.
508 MB / 512 MB limit). -
Exit Code 126 / 127: Flags missing binaries or entrypoint script permission issues (
chmod +x). - Crash Loops: Tracks restart frequency and isolates the exact stderr cause from the last seconds of the lifecycle.
π Visual Docker Compose Dependency Tree
Have you ever opened a directory with a 400-line docker-compose.yml and wished you could just see the topology?
Pressing c in Dockeretior (or running dockeretior --compose) scans local Compose files, analyzes the Directed Acyclic Graph (DAG) of depends_on, and renders an ASCII architectural diagram:
π¦ STACK: docker-compose.yml (4 services, 2 networks, 1 volume)
ββ Level 1: Ingress / Frontend / Entrypoint ββ
ββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β π api β β π traefik β
β img: mycompany/api:v1.0 β β img: traefik:v2.10 β
β ports: 8080:8080 β β ports: 80:80,443:443 β
ββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β
βΌ (depends_on)
ββ Level 3: Databases / Cache / Storage ββ
ββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β ποΈ postgres β β β‘ redis β
β img: postgres:16-alpine β β img: redis:7-alpine β
β vols: 1 mounted β β net: internal β
ββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
ββ Dependency & Link Matrix ββββββββββββββββββββββββ
β’ api ββdepends_onβββΆ [postgres, redis]
π€ #BuiltWithAntigravity: How It Came to Life
Building high-performance terminal software in Go is notoriously tricky:
- You have to handle strict ANSI escape sequences and raw terminal modes (
MakeRaw). - Terminal resize events (
SIGWINCH) must be handled without tearing or buffer scrollbars. - Go's build system has strict OS rules (e.g., naming a file
*_windows.goexcludes it from Linux/macOS builds). - Concurrency between Docker event streams, PTY forwarders, and UI event loops must be rock-solid.
This entire project was engineered pair-programming with Google Antigravity using the #builtwithantigravity agentic workflow.
What Google Antigravity enabled:
-
Mathematical Layout Budgeting: We ensured that every line rendered in the split-screen view calculates exact cell widths with
go-runewidth, guaranteeing zero terminal line-wrapping or viewport scroll jumps across any window size (from compact 80x24 laptops to 4K ultrawide monitors). - Deep Docker SDK Integration: Implementing custom socket discovery (standard Unix socket, Docker Desktop macOS, Colima, OrbStack, and Linux rootless sockets).
-
From Idea to Published Release: In just a single continuous session, Antigravity helped:
- Structure the comprehensive 11-phase architecture roadmap.
- Implement the root-cause analysis rules engine.
- Build the Compose DAG parser and ASCII box drawer.
- Write comprehensive unit tests for every package (
go test -v ./...). - Package CLI commands (
--doctor,--compose,--test-alert). - Tag and publish release versions (
v1.1.0throughv1.3.0) directly to GitHub.
Pairing with an AI agent that understands deep systems-level programming, TTY intricacies, and Unix semantics was a game-changer for shipping this tool so quickly and robustly.
π Quickstart: Try It in 30 Seconds
Option 1: Build from Source (Go 1.22+)
# 1. Clone the repository
git clone https://github.com/mario-ezquerro/dockeretior.git
cd dockeretior
# 2. Build the binary
make build
# 3. Test instant diagnostics
./bin/dockeretior --doctor
# 4. Launch the full interactive TUI
./bin/dockeretior
Option 2: Install via go install
go install github.com/mario-ezquerro/dockeretior/cmd/dockeretior@latest
β¨οΈ Essential Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| F1 / ? | Help Modal: Instant list of all keys and shortcuts |
| F2 / f | Filter: Toggle between Running only and All containers |
| F3 / l | Live Logs: Real-time container log streaming |
| F4 / e |
Exec Shell: Drop into an interactive container shell (bash/sh) |
| F5 / r | Restart: Restart the selected container |
| F6 / s | Stop / Start: Gracefully toggle container power state |
| F7 / p | Pause / Unpause: Freeze or unfreeze container processes |
| F8 / x |
Delete: Delete container (with confirmation dialog or f to force) |
| F9 / i | Inspect: View formatted container JSON configuration |
| F10 / q | Quit: Cleanly exit and restore terminal state |
| a | AutoDoctor: Open server health score & root-cause report |
| c | Compose / Prune: Open Compose topology or assisted 1-click disk cleanup |
| t | Topology Toggle: Switch between visual DAG tree and directory explorer |
π‘ What's Coming Next?
The roadmap for Dockeretior includes:
- Ephemeral Test-Restore Backups: Automated database dumps (PostgreSQL, MySQL) tested in ephemeral scratch containers to verify that your backup can actually be restored before disaster strikes.
- Explain My Server: Natural language host inspection based on real diagnostic data.
- Docker Fleet Manager: Managing multiple remote Docker hosts from a single central terminal.
Check out the code, star the project, and give it a spin:
β GitHub: https://github.com/mario-ezquerro/dockeretior
What's the most frustrating Docker issue you run into when administering remote servers? Let me know in the comments below!
Top comments (0)