Docker output,made readable.

What eza is to ls, dok is to Docker: containers, images, logs and disk usage, printed for a person to read.

$brew install alsaadii98/tap/dok
Read the manual →
dok ps -a, dok images, dok logs and dok events rendering in a terminal

One socket. No shell-out.

dok talks to the Docker API directly and lays out every table itself. It only ever reads, so it is safe to point at production.

  1. socketdocker.sockor DOCKER_HOST, or a named pipe
  2. clientbollardthe Docker HTTP API, in Rust
  3. viewssrc/dk.rsnames, compose labels, health
  4. layoutsrc/table.rsmeasure, cap, shrink, pad
  5. paintsrc/theme.rsroles, glyphs, layout
  6. outyour terminalor a pipe, or --json

11 Docker API calls, all reads0 calls to the docker CLI17 commandsHow it works, in detail →

Read, never write.

Every command prints one screen and exits, so it pipes into grep and less like anything else. Pick one to see it run.

List containers, grouped by compose project

dok-ps(1) →
Output of dok ps

Pipe it anywhere.

--json works on every command and carries what docker does not give you: the compose project, the service name, the health verdict.

$ dok ports --json | jq '.ports[] | select(.host_port == 5432)'
{
  "conflict": false,
  "container": "postgres",
  "container_port": 5432,
  "host_ip": "127.0.0.1",
  "host_port": 5432,
  "project": "demo-shop",
  "protocol": "tcp",
  "state": "running"
}
# every service that is not healthy
$ dok health --json | jq -r '.checks[] | select(.status != "healthy") | .container'
# how much a prune would free
$ dok prune --json | jq -r .total.human
# only stderr, as it arrives
$ dok logs -f --json | jq -c 'select(.stream == "stderr")'

10 themes. Palette, glyphs and layout.

A theme changes more than colour: its glyph set and table layout too, so ascii stays pure ASCII for CI logs. Start from any of them in ~/.config/dok/config.toml.

default

one-dark palette, rounded unicode

dok ps --theme default

dracula

high-contrast purples, heavy blocks

dok ps --theme dracula

nord

cool arctic palette, slim glyphs

dok ps --theme nord

gruvbox

warm retro palette, ruled headers

dok ps --theme gruvbox

catppuccin

soft pastels, slim glyphs

dok ps --theme catppuccin

tokyonight

neon night palette, grid rules

dok ps --theme tokyonight

solarized-light

for light terminals

dok ps --theme solarized-light

mono

greyscale only, weight over hue

dok ps --theme mono

matrix

all green, heavy blocks

dok ps --theme matrix

ascii

no unicode anywhere, plain rules

dok ps --theme ascii

9 ways in.

One static binary, no runtime. It needs a reachable Docker daemon and honours DOCKER_HOST. Try it with no daemon at all: every command takes --demo.

$ brew install alsaadii98/tap/dok

macOS and Linux. Installs shell completions too.

It tells you when it is old.

Once a day at most, dok checks for a release and prints one dim line after its output. Never when piped, never with --json. A packaged install gets its package manager’s command instead of an overwrite.

dok 0.3.0 is out, run `dok update`

$ dok update --check   # report only
$ dok update           # install, after asking

For reading, not driving.

lazydocker is the right tool when you want to drive containers. dok is for when you want to read them.

Capabilitydokdocker ps --formatdopslazydocker / oxker
Static, pipeable outputyesyesyesno, full-screen TUI
Grouped by compose projectyesnonopartial
Readable inspect, secrets maskedyesnonopartial
Which container owns a portyesnonono
Disk usage, biggest offendersyesnonopartial
JSON with derived fieldsyesraw onlynono
Themes: palette, glyphs, layoutyesnonono
Start, stop, exec, removeno, by designnonoyes

Questions

How do I make docker ps output readable?

Run dok ps. It reads the Docker socket directly and prints containers grouped by compose project with coloured state dots, health marks, short ids, published ports and relative ages, sized to your terminal width.

How do I find which container is using a port?

Run dok ports. It prints every published port across every container in one flat table sorted by host port, so finding the owner of 5432 is a glance or a grep. It skips exposed-but-unpublished ports, collapses the IPv4 and IPv6 rows Docker reports for a wildcard binding into one row, and marks any address, port and protocol claimed by two containers.

What is a good docker ps alternative?

dok ps is a drop-in read-only alternative to docker ps. Unlike docker ps --format it groups containers by compose project and shows the service name rather than the mangled container name, renders sizes and ages in human units, and shrinks columns to fit the terminal instead of wrapping.

How do I find which Docker image layer is making an image large?

Run dok history <image>. It lists every layer top-down in build order with a bar showing its share of the image, marks each layer over 10% of the total, and recovers the Dockerfile instruction from both the classic builder and BuildKit instead of showing /bin/sh -c #(nop).

How do I see why a Docker healthcheck is failing?

Run dok health. It lists only the containers that declare a healthcheck, sorted with unhealthy first, showing the failing streak, the healthcheck interval, the probe's exit code and the first line of its output.

How do I get JSON output from docker ps?

Run dok ps --json. Every dok command takes --json and emits the same data the table shows, including the derived fields docker does not give you: the compose project, the service name, the health verdict. Sizes and ages arrive as both the number and the human rendering, so nothing has to be re-parsed. dok logs and dok events emit NDJSON, one object per line, because they are streams.

What will docker system prune delete?

Run dok prune. It shows exactly what docker system prune would remove. stopped containers, dangling images, unused networks and build cache. grouped by kind and sized, without removing anything. It draws the same line docker does: dangling images by default, every unused image with -a, volumes only with --volumes. It then prints the docker command that does the removing.

Does dok have shell completions?

Yes. dok completions <shell> prints a script for bash, zsh, fish, nushell, powershell or elvish, generated from the same definition the CLI is built from. Homebrew installs them automatically; the .deb and .rpm include bash, zsh and fish; every release attaches a tarball with all six.

Is there a readable alternative to docker inspect?

dok inspect folds the inspect JSON into identity, state, config, resources, network, mounts and labels, masks credential-looking environment values by default, and highlights privileged mode, added capabilities, OOM kills and failing healthchecks.

How is dok different from lazydocker or ctop?

lazydocker and ctop are full-screen TUIs you drive interactively. dok prints one static, pipeable screen per command and is read-only: it never starts, stops, execs into or removes containers.

How do I install dok?

brew install alsaadii98/tap/dok, cargo install dok-cli, makepkg from the PKGBUILDs in the repo on Arch, apk add --allow-untrusted ./dok-x86_64.apk on Alpine, the .deb or .rpm from the releases page, nix run github:alsaadii98/dok, or scoop bucket add dok https://github.com/alsaadii98/dok followed by scoop install dok/dok on Windows.

How do I update dok?

Run dok update. dok checks GitHub for a newer release at most once a day and prints a one-line notice after a command's output. A standalone binary is replaced in place after its release checksum is verified; if dok was installed by brew, apk, dpkg, rpm or cargo it prints that package manager's upgrade command instead. Set DOK_NO_UPDATE_CHECK=1 to disable the check.