default
one-dark palette, rounded unicode
dok ps --theme defaultWhat eza is to ls, dok is to Docker: containers, images, logs and disk usage, printed for a person to read.
brew install alsaadii98/tap/dokdok talks to the Docker API directly and lays out every table itself. It only ever reads, so it is safe to point at production.
docker.sockor DOCKER_HOST, or a named pipebollardthe Docker HTTP API, in Rustsrc/dk.rsnames, compose labels, healthsrc/table.rsmeasure, cap, shrink, padsrc/theme.rsroles, glyphs, layoutyour terminalor a pipe, or --json11 Docker API calls, all reads0 calls to the docker CLI17 commandsHow it works, in detail →
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) →Every published port in one table, sorted by port
dok-ports(1) →Containers with a healthcheck: status, failing streak, last probe
dok-health(1) →Layers of an image with size bars and readable instructions
dok-history(1) →What docker system prune would remove. Never removes anything
List images with size and age gradients
dok-images(1) →Disk usage by images, containers, volumes and build cache
dok-df(1) →Readable summary of a container's configuration and state
dok-inspect(1) →Tail logs from one or more containers with level colouring
dok-logs(1) →Processes running inside containers, as a tree
dok-top(1) →Tree view of compose projects, networks and volumes
dok-tree(1) →Live daemon event stream, colour-coded
dok-events(1) →List or preview themes
dok-themes(1) →--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")'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.
one-dark palette, rounded unicode
dok ps --theme defaulthigh-contrast purples, heavy blocks
dok ps --theme draculacool arctic palette, slim glyphs
dok ps --theme nordwarm retro palette, ruled headers
dok ps --theme gruvboxsoft pastels, slim glyphs
dok ps --theme catppuccinneon night palette, grid rules
dok ps --theme tokyonightfor light terminals
dok ps --theme solarized-lightgreyscale only, weight over hue
dok ps --theme monoall green, heavy blocks
dok ps --theme matrixno unicode anywhere, plain rules
dok ps --theme asciiOne 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/dokmacOS and Linux. Installs shell completions too.
$ cargo install dok-cliAny platform with Rust 1.88+. The crate is dok-cli; the binary is dok.
$ git clone https://github.com/alsaadii98/dok
$ cd dok/packaging/aur
$ makepkg -si -p PKGBUILD-binPrebuilt binary. Drop -p PKGBUILD-bin to build from source.
$ curl -LO https://github.com/alsaadii98/dok/releases/latest/download/dok_amd64.deb
$ sudo dpkg -i dok_amd64.debDebian and Ubuntu. Includes completions for bash, zsh and fish.
$ curl -LO https://github.com/alsaadii98/dok/releases/latest/download/dok.x86_64.rpm
$ sudo rpm -i dok.x86_64.rpmFedora and RHEL. Includes completions.
$ wget https://github.com/alsaadii98/dok/releases/latest/download/dok-x86_64.apk
$ apk add --allow-untrusted ./dok-x86_64.apkStatic musl binary, no dependencies. aarch64 too.
$ nix run github:alsaadii98/dokOr nix profile install github:alsaadii98/dok.
$ scoop bucket add dok https://github.com/alsaadii98/dok
$ scoop install dok/dokThis repository doubles as a scoop bucket.
$ git clone https://github.com/alsaadii98/dok
$ cd dok && cargo build --releaseThe binary lands in target/release/dok.
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 askinglazydocker is the right tool when you want to drive containers. dok is for when you want to read them.
| Capability | dok | docker ps --format | dops | lazydocker / oxker |
|---|---|---|---|---|
| Static, pipeable output | yes | yes | yes | no, full-screen TUI |
| Grouped by compose project | yes | no | no | partial |
| Readable inspect, secrets masked | yes | no | no | partial |
| Which container owns a port | yes | no | no | no |
| Disk usage, biggest offenders | yes | no | no | partial |
| JSON with derived fields | yes | raw only | no | no |
| Themes: palette, glyphs, layout | yes | no | no | no |
| Start, stop, exec, remove | no, by design | no | no | yes |
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.