cdd-cli
v4.12.1
Published
CLI Docker Dashboard
Maintainers
Readme
CDD — CLI Docker Dashboard
A terminal dashboard for Docker containers — monitor, manage, and create, all without leaving your keyboard.
🎉 What's new in v4.12
The log viewer is now a proper tool, and CDD keeps itself up to date.
- The viewer scrolls and pauses.
↑/↓andPgUp/PgDnmove through the buffer; scrolling up pauses following, the header counts the lines that arrive meanwhile, andEnd(orf) catches up. These keys were listed in the help but did nothing (D21). /searches the logs. Matches are highlighted and counted (3 of 27),n/Njump between them with wrap-around, andCtrl+Fkeeps only the matching lines. The search is literal and ignores case.- CDD tells you when a newer version is on npm — and can update itself. On start it checks the registry quietly (at most once a day, in the background); when there is a newer release the header shows
↑ vX.Y.Z [U], andUruns the right install command for npm, pnpm, yarn or bun after asking. Opt out withCDD_NO_UPDATE_CHECK=1.
Along the way, four rendering and health bugs were fixed: the stats bars no longer touch the rows around them, a stopped container is no longer shown as unhealthy just because Docker kept its last health status, log lines no longer start with stray bytes from Docker's stream framing, and opening the logs, help or diagnosis no longer stacks copies of the screen on scrollback.
Requires Node 22 or newer — the supported range now matches what the dependency tree already needed (ink 8, chalk 6).
Older release notes are kept in CHANGELOG.md.
Features
- 🐳 Live view of all Docker containers with CPU/memory stats
- 🔄 Auto-refresh every few seconds — always up to date
- ⌨️ Keyboard-driven actions: start, stop, restart, log streaming, removal
- 🎨 Health verdicts — running, starting, stopped, crashed, crash-loop, restarting or unhealthy, read from Docker's own data
- ⚪ Stopped vs crashed — a container you stopped is grey; red is reserved for real failures
- 🔍 Explains why it failed — a panel with the probable cause and the last log lines, unprompted, for every failing container
- 🔧 One-key fix —
Frecreates the container with the correction applied, on a review screen that shows exactly what changed - 🤝 "I don't recognise it" — when no rule matches, CDD says so instead of guessing, and shows the evidence
- ✨ Interactive creation wizard — step-by-step container setup with curated profiles and live Hub search
- 🪵 Real-time log streaming for any selected container
- 🐛 Toggleable live debug panel (
Dkey) - 🚨 Smart connection handling — clear error screen with actionable suggestions when Docker is unreachable
Install globally
npm install -g cdd-cli
cddQuick start (local)
git clone https://github.com/caertos/cdd.git
cd cdd
pnpm install
pnpm run build
node dist/index.jsTo use as a global command during development:
pnpm link --global
cddUsage
Use ↑ / ↓ to navigate containers. The HUD at the bottom shows available keys for the current context. Press ? for full help.
Container List
| Key | Action |
| --------- | --------------------------------------------------------- |
| ↑ / ↓ | Navigate container list |
| I | Start selected container |
| P | Stop selected container |
| R | Restart selected container |
| C | Open creation wizard |
| F | Fix — recreate with the diagnosis applied (only shown when there is a fix) |
| L | Stream logs for selected container |
| S | Open interactive shell inside selected container |
| E | Erase (remove) selected container — confirmation required |
| D | Toggle live debug panel |
| Q | Quit |
| U | Update CDD — only shown when a newer version is on npm |
| ? | Show help panel for the current screen |
After F creates the replacement, y deletes the container that failed and n keeps it. Those two keys only exist while the question is on screen.
Connection Screen
| Key | Action |
| --------- | --------------------------------------------------- |
| S | Start Docker (only when CDD knows how) |
| R | Retry container fetch immediately |
| Q | Quit CDD (no confirmation) |
| — | Auto-retry every 5 seconds (shown as a live countdown) |
Starting Docker from the connection screen
When Docker is unreachable, CDD checks whether it knows how to start it. If it does, the S key appears and walks you through launching Docker without leaving the terminal.
- Windows — CDD finds Docker Desktop in its standard install locations and starts it directly, with no password. This is the primary platform.
- macOS — opens Docker Desktop with
open -a Docker. - Linux (rootless) — starts the user service (
systemctl --user start docker) without a password. - Linux (system service) — hands the terminal over to
sudo systemctl start dockerso you can type your password.
After starting, CDD waits for the daemon to respond, then reloads your containers automatically. On Windows, a slow start usually means the WSL2 engine is still initializing — CDD offers to keep waiting.
S only appears when CDD knows how to start Docker, and CDD never offers to stop Docker.
Creation Wizard
| Key | Action |
| --------- | ----------------------------------------- |
| Enter | Confirm and continue to next step (or create on review) |
| Esc | Go back one step (or cancel on step 0) |
| Tab | Search Docker Hub (step 0) or insert env |
| ↑ / ↓ | Navigate suggestions |
| Ctrl+G | Generate a strong secret (step 3) |
| Ctrl+R | Toggle secret visibility (step 3) |
| 1–4 | Edit a field from the review screen |
| ? | Show help panel |
Logs Viewer
The log opens in a panel under the list. Scrolling up pauses following (the header says so and counts the lines that arrive meanwhile); End goes back to the newest line and follows again.
| Key | Action |
| --------------- | --------------------------------------------------- |
| ↑ / ↓ | Scroll one line |
| PgUp / PgDn | Scroll one page |
| Home / End | First line / newest line (and follow again) |
| f | Toggle auto-follow |
| / | Search: matches are highlighted and counted |
| n / N | Next / previous match |
| Ctrl+F | Show only the matching lines (toggle) |
| Enter / Esc | In the search field: keep the search / clear it |
| Esc / Q | Close logs viewer |
| ? | Show help panel |
Confirmation
| Key | Action |
| --- | --------------------- |
| y | Confirm the action |
| n | Cancel the action |
Updates
On start, CDD checks the npm registry in the background for a newer release — at most once a day, with a 3 second timeout, and no data beyond the public version manifest. When one exists, the header shows it next to the version (v4.11.1 · ↑ v4.12.0 [U]) and U runs the install command for the package manager that installed CDD (npm, pnpm, yarn or bun) after asking. Running through npx or from a source checkout? CDD shows the command instead of running it.
Turn the check off with CDD_NO_UPDATE_CHECK=1 or NO_UPDATE_NOTIFIER=1.
The Diagnosis Panel
When the selected container is failing, CDD explains it. You do not press anything.
It appears only when there is something to say. A container you stopped, or one still starting up, gets no panel — there is nothing to explain and the space is better kept.
It always has the same three parts, in this order:
- What happened — from the container's health verdict. Always present.
- Likely cause — from the rule catalog. May be missing, and when it is, the panel says so.
- Last lines — the last five lines of its log. It is what you were about to go and look at.
When CDD doesn't know
Likely cause:
I don't recognise it. This is the last thing the container
said before it died:This is principle 5 of the project and it is not negotiable. A confident-sounding wrong cause costs more trust than ten correct ones build — and "I don't know, but here is the evidence" is still useful, because it saves you opening the log viewer.
The rules
| Rule | Recognised by | What it offers |
|---|---|---|
| Missing Postgres password | superuser password is not specified | Recreate with POSTGRES_PASSWORD |
| Missing MySQL / MariaDB password | you need to specify one of MYSQL_ROOT_PASSWORD | Recreate with the variable |
| Missing SQL Server EULA | ACCEPT_EULA in the log | Recreate with ACCEPT_EULA=Y |
| Host port in use | port is already allocated / address already in use | Recreate with another free port |
| Image has no command | no command specified | Explains; no automatic fix |
| Out of memory | OOMKilled in Docker's own data | Explains; suggests raising the limit |
| Volume permission denied | permission denied on a path | Explains; no automatic fix |
| Executable not found | executable file not found in $PATH | Explains |
| Clean quick exit | Exit code 0 in under 2 seconds | Explains that the image finished its job and is not a service |
| Connection refused | connection refused | Explains; may mean a missing network |
They are data, not code: an array of rules with a priority. A rule only fires on evidence CDD actually read — a log line or an inspect fact. Adding one is adding an element to a list and a case to its test file.
Recreating with the fix
F opens the wizard already filled in and already on the review step, because the interesting thing to check is the diff, not the image name:
[4] Env POSTGRES_PASSWORD=•••••• ↑ changed by CDD
POSTGRES_DB=app- Nothing is applied behind your back. The fix goes through the review, you confirm it.
- The failed container keeps its name, so the replacement becomes
mi-basedatos-2. - The wizard's own env field is filtered. Docker merges the image's variables into the container's, so
PATH,LANGandPG_VERSIONwould otherwise fill the form. CDD subtracts the image's own before showing yours. - Secrets start masked, every time, even if you revealed them in an earlier wizard.
- When the fix needs a value only you have — a password — the key says "Recreate and set POSTGRES_PASSWORD" and the review warns that the variable is set but empty. CDD will not invent a password.
Two limits worth knowing
- Recreating carries over the image, name, ports and variables. It does not carry over
Cmd,Entrypoint, volumes, networks or restart policy — the wizard has no fields for them. - The env field is comma-separated and Docker allows commas inside a value. A variable with a comma is split. The
kafkaprofile already ships one.
The Creation Wizard
Press C from the dashboard to launch the wizard. A context-sensitive HUD at the bottom always shows which keys are active at each step — no guessing required.
Step 0 — Image
Type to filter through 20 curated offline profiles (postgres, redis, nginx, node, mysql, mongo, python, golang, and more). Results appear instantly.
Press Tab at any time to search Docker Hub live. A [searching Docker Hub...] indicator confirms the search is running. Use ↑ / ↓ to navigate suggestions, Enter to select.
Smart default tags: selecting an image profile automatically applies a known-good tag — postgres:17-alpine, redis:7-alpine, nginx:1.27-alpine, etc. No more containers that fail silently because of a stale :latest.
Step 1 — Container name
Free-text input. Give your container a memorable name.
Step 2 — Port mapping
Enter a port mapping in HOST:CONTAINER format, e.g. 8080:80, 5432:5432. Leave blank to skip.
Step 3 — Environment variables
Enter KEY=VALUE pairs one at a time. Contextual hints show recommended variables for the selected image:
| Image | Suggested vars |
| --------------------- | ---------------------------------------------------------- |
| postgres | POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB |
| mysql | MYSQL_ROOT_PASSWORD, MYSQL_DATABASE |
| redis | (no required vars) |
| mongo | MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD |
| node / nginx / others | Common runtime vars as applicable |
Secret variables (PASSWORD, SECRET, TOKEN, API_KEY, etc.) are automatically masked as you type. Use Ctrl+R to reveal them temporarily, or Ctrl+G to generate a strong password with one keystroke.
Press Enter on an empty line to finish and create the container.
Interactive Shell
Press S from the dashboard while a running container is selected. CDD will:
- Detect the available shell inside the container (
bashorsh) - Open a full interactive terminal session
- Drop you into the container's shell
From there you can run any command — psql for PostgreSQL, python3 for Python, node for Node.js, redis-cli for Redis, etc.
Type exit or press Ctrl+D to leave the shell and return to the CDD dashboard.
Requirements
- Node.js >= 22
- Docker installed and running (CDD connects to the local Docker socket)
Development
pnpm install
pnpm run build # compile src/ → dist/
node dist/index.js # run from compiled outputRe-run pnpm run build after any source changes. Use pnpm link --global to test the global cdd command locally.
Tests
pnpm testTests live in test/ and cover helpers, services, and hooks.
Logging
By default CDD shows info, warn, and error messages. For deeper diagnostics:
CDD_LOG_LEVEL=debug cddPress D inside the dashboard to toggle the live debug panel in real time. Press D again to hide it.
To capture logs to a file:
CDD_LOG_LEVEL=debug cdd > cdd-debug.log 2>&1Troubleshooting
- No containers visible? If Docker is running but no containers appear, you may have none running or created. Press
Cto create one. If Docker is unreachable, CDD now shows a clear error screen with instructions to fix it. - Docker connection error? CDD will show "Can't reach Docker" with specific steps to resolve it. Press
Rto retry after fixing the issue, wait for the live countdown, or pressQto quit. - The panel says "I don't recognise it"? CDD only explains what its rule catalog recognises, and it would rather admit that than guess. The last lines are right there — press
Lfor the full log. Fisn't showing? The key appears only when the diagnosis carries a fix. Most causes are explained but not repairable (an image with no command, a denied volume), and a key that opens a wizard with nothing to change would be noise.Fsays it couldn't read the container's configuration? CDD refuses to recreate a container whose environment it could not read, rather than building one with no variables — which would die the same way. PressCto create one from scratch.- A fix left a password field empty on purpose. CDD will not invent a password. Fill it in on the review screen before creating, or the container will fail again exactly as it just did.
- Permission errors on Linux/macOS? Try
sudo cddor add your user to thedockergroup. - Windows? Run your terminal as Administrator.
dist/missing? Runpnpm run build— it's in.gitignoreand not committed.- Wizard search not working? Check your internet connection. Offline profiles always work without network access.
Contributing
See CONTRIBUTING.md.
License
MIT/ISC — see LICENSE.
