v0.4.0 · MIT · Node 24+

Docker at terminal speed.

A lightweight TUI for Docker. Watch and control your Compose stacks, follow logs, see what uses what, and clean up what's left behind — without leaving the terminal.

$ npx dockza.app
ornpm install -g dockza.app
◆ dockza v0.4.0 · docker 27.3.1 unix:///var/run/docker.sock
cpu 31.1% mem 3.3 GiB ● 7 running ● 1 err 3 stop
VIEW
▌◰Stacks3
◧Containers11
◩Images16
◪Volumes11
◫Networks7
STACKS
●acme6
●storefront3
○scratch2
STACK · SERVICESTATECPUMEMPORTS
▾ ▣ acme [4 up] [1 err] [1 stop] live
├─ ● acme-api-1 ghcr.io/acme/api:1.9 RUN 4d 2h 18.6%28.4% 0.0.0.0:8080->8080/tcp
├─ ● acme-postgres-1 postgres:16-alpine RUN 4d 2h 1.2%12.8% 5432/tcp
├─ ● acme-redis-1 redis:7-alpine RUN 4d 2h 0.4%3.1% 6379/tcp
├─ ● acme-worker-1 ghcr.io/acme/api:1.9 RUN 4d 2h 7.4%31.2% —
├─ ● acme-migrate-1 ghcr.io/acme/api:1.9 EXIT 1 —— —
└─ ● acme-pgadmin-1 dpage/pgadmin4:8.12 EXIT 0 · 3d —— 80/tcp +1
▾ ▣ storefront [3 up] live
├─ ● storefront-minio-1 minio/minio:latest RUN 6h 12m 2.6%14.1% 0.0.0.0:9000->9000/tcp
├─ ● storefront-nginx-1 nginx:1.27-alpine RUN 6h 12m 0.1%2.4% 0.0.0.0:80->80/tcp
└─ ● storefront-web-1 ↑ storefront-web:dev RUN 6h 12m 0.8%9.6% 0.0.0.0:3000->3000/tcp
▸ ▣ scratch [2 stop] —
↑↓nav ↵detail llogs xshell sstop rrestart kkill /filter [ ]back/fwd hhelp
last refresh 1s ago

Stacks — containers grouped by Compose project, with live counts per stack. The orange ↑ marks a container running an outdated image.

Five views, one keystroke apart.

Press 1–5 to jump, Tab to cycle, / to filter any list as you type, Enter to open whatever row you're on. The rail stays put and keeps a live list of your stacks — click one to jump straight into it.

  • 1◰StacksCompose projects as a collapsible tree, with running / errored / stopped counts per project.
  • 2◧ContainersEvery container, flat: status and uptime, network, live CPU and memory, published ports.
  • 3◩ImagesRepository, tag, ID, age, size — and USED BY: the containers created from each one.
  • 4◪VolumesDriver, mountpoint, size and USED BY. Leftovers are marked orphaned or dangling.
  • 5◫NetworksDriver, scope, ID, age, and USED BY: every container attached, running or stopped.

Everything links.

Enter opens a detail panel for any container, image, volume, network or stack. A container's shows its image and stack, each published port with a URL, its address and DNS names on every network, its mounts, the containers it depends on, and its environment.

Tab moves between sections, Enter follows a link to the thing it names, and [ / ] walk back and forward through where you've been.

DETAIL — acme-api-1
acme-api-1ghcr.io/acme/api:1.9 · 84ff5a44f2d1
● running
Uptime:4d 2h
Restart:unless-stopped
PIDs:18342
CPU[████░░░░░░░░░░░░░░░░]18.6%
MEM[██████░░░░░░░░░░░░░░]28.4%(582 MiB / 2.0 GiB)
DISKR:1.2 GiBW:340 MiB
RELATED (2)↑↓ select · ↵ open · y copy · Tab next
imageghcr.io/acme/api:1.9
stackacme· service api
PORTS (1)Tab select
0.0.0.0:8080→ 8080/tcphttp://localhost:8080
NETWORKS (1)Tab select
acme_default172.19.0.4acme-api-1, api
MOUNTS (1)Tab select
bind/srv/acme/uploads→ /data/uploadsrw
DEPENDS ON (2)Tab select
depends on● acme-postgres-1(compose depends_on: postgres)
depends on● acme-redis-1(compose depends_on: redis)
ENV (14) ▸Tab / e show
[s] Stop[r] Restart[k] Kill[x] Shell[l] Logs[e] Env[y] CopyEsc close
↑↓select ↵open ycopy Tabnext Escclose [ ]back/fwd
last refresh 1s ago

Stop a whole stack — or take it down.

On a stack header, s, S, r and k stop, start, restart or kill every service in it — dependencies start first and stop last, as compose does.

Stop asks how far to go: y only stops, d takes the stack down like docker compose down, v adds -v. Networks and volumes another container still uses are kept. It all goes through the Docker API, so it works against a remote daemon too.

STACK · SERVICESTATECPUMEM
▾ ▣ acme [4 up] [1 err] [1 stop] live
├─ ● acme-api-1 ghcr.io/acme/api:1.9 RUN 4d 2h 18.6%28.4%
├─ ● acme-postgres-1 postgres:16-alpine RUN 4d 2h 1.2%12.8%
├─ ● acme-redis-1 redis:7-alpine RUN 4d 2h 0.4%3.1%
├─ ● acme-worker-1 ghcr.io/acme/api:1.9 RUN 4d 2h 7.4%31.2%
├─ ● acme-migrate-1 ghcr.io/acme/api:1.9 EXIT 1 ——
└─ ● acme-pgadmin-1 dpage/pgadmin4:8.12 EXIT 0 · 3d ——
↑↓nav ↵detail sstop rrestart kkill ddown …
last refresh 1s ago
Stop stack acme?
4 of 6 services running.
[y]Stopkeep its containers and data
[d]Downremove 6 containers, 1 network · keep volumes
[v]Down -valso delete 3 volumes
[n]Cancelor Esc

Clean up without the guesswork.

USED BY names the containers holding on to each image, volume and network. A volume left behind by a removed compose project reads ○ orphaned; an anonymous one nothing mounts reads ○ dangling.

Mark rows with Space — or a for every row shown — and d deletes them together. D clears out a whole kind of volume at once, with the count and the space it frees shown first. Anything in use is skipped, and the built-in bridge, host and none networks are never touched.

NAMEDRIVERUSED BYMOUNTPOINTSIZESTATUS
2 marked
386af951f751b36024013deb8e9249e9085a4e62e379dc38c0f58af0e0aae12dlocal—/var/lib/docker/volumes/386af951f751b36024013deb8e9249e9085a4e62e379dc38c0f58af0e0aae12d/_data1 MiB○ dangling
76804036e6b68b7ea567c19b2a59c35fbd7d926dc94ef66f6c9306d643f8829elocal● acme-redis-1/var/lib/docker/volumes/76804036e6b68b7ea567c19b2a59c35fbd7d926dc94ef66f6c9306d643f8829e/_data12 MiB● in use
94e499e83738ad6ad126c4ec6524e7fc2313977f62224b8ee2824acaa31b57b1local—/var/lib/docker/volumes/94e499e83738ad6ad126c4ec6524e7fc2313977f62224b8ee2824acaa31b57b1/_data96 MiB○ dangling
acme_pgadminlocal● acme-pgadmin-1/var/lib/docker/volumes/acme_pgadmin/_data38 MiB● in use
acme_pgdatalocal● acme-postgres-1/var/lib/docker/volumes/acme_pgdata/_data1.8 GiB● in use
✓fa533a1f9605268f25841e1b5cf41b4fa36573b163b4216744934f3f7725af59local—/var/lib/docker/volumes/fa533a1f9605268f25841e1b5cf41b4fa36573b163b4216744934f3f7725af59/_data214 MiB○ dangling
✓oldshop_medialocal—/var/lib/docker/volumes/oldshop_media/_data731 MiB○ orphaned
oldshop_pgdatalocal—/var/lib/docker/volumes/oldshop_pgdata/_data2.1 GiB○ orphaned
pip-cachelocal—/var/lib/docker/volumes/pip-cache/_data287 MiB○ unused
scratch_mysqllocal● scratch-db-1/var/lib/docker/volumes/scratch_mysql/_data412 MiB● in use
storefront_minio-datalocal● storefront-minio-1/var/lib/docker/volumes/storefront_minio-data/_data3.2 GiB● in use
ddelete 2 Dclean up Spacemark aall Escunmark …
last refresh 1s ago
Clean up volumes?
Deleted for good; nothing in use is touched.
[d]Dangling3 volumes · 311 MiBanonymous, and no container mounts them
[o]Orphaned2 volumes · 2.8 GiBtheir compose project has no containers left
[u]All unused6 volumes · 3.4 GiBevery volume no container mounts
[n]Cancelor Esc

Logs that keep up.

l streams a container's log straight into the pane, with stderr in orange. f toggles follow, g and G jump to top and bottom, and a 5,000-line scrollback cap keeps a chatty container from running away with your memory. Enter opens the container's detail; [ brings you back.

LOGS — acme-api-1
2026-10-09T14:02:11.812Z info http server listening on :8080
2026-10-09T14:02:11.902Z info connected to postgres acme_default
2026-10-09T14:02:12.114Z info worker pool ready (4)
2026-10-09T14:02:18.441Z info GET /healthz 200 1.2ms
2026-10-09T14:02:19.006Z warn slow query 812ms on orders
2026-10-09T14:02:19.550Z info GET /api/orders 200 44ms
2026-10-09T14:02:20.907Z info POST /api/orders 201 61ms
2026-10-09T14:02:21.318Z error upstream timeout: payments
2026-10-09T14:02:22.004Z info retry succeeded: payments 340ms
2026-10-09T14:02:24.771Z info GET /api/orders/8812 200 9ms
↵detail ffollow gtop Gbottom ↑↓scroll Escclose …
last refresh 1s ago

Small things that add up.

/

Filter as you type

Every list narrows with each key, and matches past the name: image, ID, any tag, compose project.

y

Copy what you need

A name, an ID, a port's URL, a -p or -v spec, NAME=value. System clipboard — or OSC 52 over SSH.

[ ]

Back and forward

Step through the screens you visited, followed links included, landing on the row you left.

e

Environment, in full

Browse a container's variables and expand any value — long or multi-line — to read it whole.

x

Shell in

Opens your platform's own terminal with docker exec into the selected container.

↑

Outdated images

Flags a container whose image tag now points at a newer local image; the image's detail says what superseded it.

Every key, on one card.

Press h anywhere in the app for the full reference, without leaving what you were doing.

Navigation

1 … 5Jump to a view
Tab / ⇧TabCycle views
[ / ]Back / forward through screens
/Filter as you type
hToggle help overlay
q / Ctrl+CQuit

Containers & stacks

EnterOpen the detail panel
l / xLog viewer / shell in
sStop, or remove / take down
S / r / kStart / restart / kill
dRemove a stopped one, or take a stack down
→ / ←Expand / collapse a stack

Detail panel

Tab / ⇧TabMove between sections
EnterFollow a link
yCopy menu
eShow / hide the environment
EscClose

Images, volumes, networks

EnterOpen the item's detail
Space / aMark a row / every row shown
dDelete it, or all marked
DVolumes: clean up by kind
EscClear the filter, then the marks

Log viewer

fToggle follow mode
g / GTop / bottom (G re-follows)
↑ / kScroll up, pausing follow
EnterOpen the container's detail

Dialogs

yConfirm — the safest option
d / vRemove or down / with volumes
d / o / uClean up: dangling / orphaned / all unused
n / EscCancel

Talks to whatever daemon you have.

dockza finds the socket on its own. When it shouldn't, DOCKER_HOST decides — rootless Docker, podman, a named pipe, or a daemon on another machine.

DOCKER_HOST=unix:///run/user/1000/docker.sock dockza# rootless docker DOCKER_HOST=unix:///run/user/1000/podman/podman.sock dockza# podman DOCKER_HOST=tcp://10.0.0.5:2375 dockza# remote daemon DOCKER_HOST=npipe:////./pipe/docker_engine dockza# windows named pipe
Node.js 24+ 256-color or truecolor terminal macOS · Linux · Windows docker CLI only for x (shell) ~100 kB package

Try it in one line.

$ npx dockza.app
No daemon reachable? dockza says so and exits — it never guesses.