dtop: a terminal Docker dashboard that treats many hosts as one table
Terminal dashboard for Docker monitoring across multiple hosts with Dozzle integration.
At a glance
- What is it?
- dtop is a Rust terminal dashboard for Docker containers, with live metrics, container actions, log streaming and a Dozzle link, reachable over local sockets, SSH, TCP or TLS. It is MIT licensed and shipping releases weekly, but it is a monitoring client, not a scheduler, and Kubernetes support is still an open roadmap item.
- Who is it for?
- Adopt dtop if your team runs Docker on more than one machine and wants a single screen instead of a fleet of SSH sessions, and if you already run Dozzle for logs. Do not expect it to replace your orchestrator: container start, stop and remove are exposed, but scheduling, rolling updates and cluster awareness are not, and Kubernetes support is an unchecked box on the roadmap.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One table of containers from every host you point it at
dtop exists because a terminal session is where many operators already live, and because `docker stats` shows one daemon at a time. The project describes itself as a terminal based dashboard for Docker that monitors multiple hosts in real time, and the feature list is short: live updates of container status and metrics, multi host support, a Dozzle link opened by keyboard shortcut, and real time log streaming. The claim of being lightweight is paired with the reason, Rust, and the dependency list backs that up: ratatui and crossterm for the interface, tokio for the async runtime, bollard for the Docker API.
The audience is an operator who needs to see a spread of machines at once and act on a container from that view, not a platform team that needs a control plane. The roadmap makes the scope plain. Sorting by name and status, log streaming, mouse scrolling, TLS certificates through DOCKER_CERT_PATH, responsive columns for a narrow view, stopping, starting and removing containers, container health status, search and filter, JSON parsing and formatting, configurable columns with saved preferences, and disk IO are all marked done. Adding support for Kubernetes clusters is the one entry left open. That single unchecked box tells you where the project intends to stop.
bollard over four transports, with a custom SSH layer underneath
The connection model is the most interesting engineering decision in the project. By default dtop talks to the local daemon over /var/run/docker.sock, and DOCKER_HOST is honoured for other machines. The --host flag takes a Docker host URL and can be repeated. The help text lists the forms it understands: `local` for the active Docker context, `unix:///path/docker.sock` for a specific socket, `ssh://user@host` and `ssh://user@host:2222` for SSH with a custom port, `tcp://host:2375` for plain TCP, and `tls://host:2376` for TLS.
The Cargo.toml shows why the SSH path is not just a flag. bollard is included with the `ssh` and `ssl` features, and the comment above `hyper` explains that a custom SSH transport was written for bollard specifically so that `ssh://` URLs with explicit ports are honoured, built on hyper, hyper-util, openssh and tower-service. Defaulting to `local` also means dtop follows the Docker CLI's own endpoint resolution, honouring DOCKER_HOST, DOCKER_CONTEXT and the active `docker context` from ~/.docker/config.json, which means it lands on the same endpoint your CLI would use rather than a second source of truth.
Installing dtop and pointing it at a remote daemon
There are five documented ways in, and picking the wrong one costs you the self-update feature later. Homebrew is the recommended path for macOS and Linux, and the note explains why: Homebrew upgrades dtop automatically, and the project is described as in active development with frequent updates.
brew install dtopThe install script downloads the latest release from GitHub:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/amir20/dtop/releases/latest/download/dtop-installer.sh | shNix users can run it without installing anything, which suits a machine where you would rather not leave a binary behind:
nix run github:amir20/dtopThere is also a container image for environments where the binary should come from the same registry as everything else:
docker run -v /var/run/docker.sock:/var/run/docker.sock -it ghcr.io/amir20/dtopThe image is built for amd64 and arm64. Note the socket mount, which is the same permission question every socket client raises. Building from source is a Cargo install, and the crate requires a recent toolchain: edition 2024 with rust-version 1.98.
cargo install dtopThe first real use is picking hosts. The help text gives the multi host form directly:
--host local --host ssh://user@server1 --host tls://server2:2376 (Multiple hosts)Pass it to dtop with the flag name and you get one table covering the local daemon plus both remote ones. For the TLS host, set DOCKER_CERT_PATH to a directory containing key.pem, cert.pem and ca.pem.
Filters that behave one way against the list and another against events
The filter syntax is where a careful reader should slow down. The --filter flag can be given more than once, and the combination rules are explicit: repeated filters of the same type use OR logic, while different types use AND logic. The help gives concrete examples, and the available keys are a wide set, id, name, label, status, ancestor, before, since, volume, network, publish, expose, health and exited.
--filter status=running --filter name=nginxThis would mean a container that is running and named nginx, while `--filter status=running --filter status=paused` widens to either state. That is ordinary and easy to reason about.
The line that should change how you test a filter is the caveat attached to the list of keys. The project states that some filters only work with container listing and not with events, and that a warning will be shown if a filter is incompatible with events. In other words, the filter you typed is understood in two different subsystems of the tool, and the semantics of the same key can differ between the initial listing and the live event stream. You can see where this bites in practice with a key like `before` or `since`, which describe a relationship to other containers and have no obvious event equivalent. The warning is the safety net, but it is a warning, not a block.
A config file that only replaces your hosts, with Ctrl-S writing it back
Preferences are handled through a config file, and the help text for --config is unusually specific about the limits of that mechanism. The file must exist, there is no flag to create one, and the note says that --host still replaces its hosts, and Ctrl-S saves preferences back to it. So the config file stores host selections and preferences such as your column choices, and the command line host list overrides the host part of it. The repository carries a config.example.yaml, and a config file can be pointed at with -c or --config.
There is one asymmetry worth knowing. The --all flag shows stopped, exited and paused containers in addition to running ones, and the documentation is explicit that it can only enable that state. If your config file contains `all: true`, you cannot turn it off from the command line; you either edit the config file or press 'a' in the interface to toggle back to running containers only. That is a small design choice, but it is the kind of detail that saves an argument later when someone wonders why a stopped container appeared in a listing they thought was scoped.
The column set is also user-controlled, with responsive layout for a narrow terminal, which is the kind of feature that matters when the dashboard is a side pane rather than a full screen.
dtop update only reaches binaries it installed itself
The built-in self-update is convenient and its boundary is clearly stated. Running dtop update checks GitHub releases for the latest version, downloads and installs it if a newer one exists, and replaces the current binary. The feature is gated by a Cargo feature flag: the default feature set is `self-update`, and the dependency is marked optional, which means you can build without it. The Dockerfile does exactly that, compiling with --no-default-features so the container image carries no updater.
dtop updateThe limitation is worth internalising. The self-update path is only available in binaries installed via the install script or downloaded from GitHub releases. Docker images should be updated by pulling the latest image, and cargo installations should use `cargo install dtop --force`. If you installed with Homebrew, the package manager owns the upgrade. Three different upgrade paths for one binary is a sign of how widely this gets deployed, and also a small operational trap: the command that feels universal is not.
Against docker stats, and against Dozzle on its own
The two comparisons worth making are with the tools this replaces. Against `docker stats`, dtop adds the part that single daemon output cannot give you: one table spanning local, SSH, TCP and TLS hosts, plus health status, disk IO, log streaming, and the ability to stop, start and remove a container without leaving the view. Against `docker ps`, the difference is the same but sharper, since ps is a snapshot and dtop updates in place.
Dozzle is a different shape of comparison, because dtop integrates with it rather than replacing it. Dozzle is the log viewing side, and dtop opens Dozzle links through keyboard shortcuts for a container in the list. The division of labour is sensible: dtop holds the metrics and the action buttons, Dozzle holds the full log view in a browser, and the shortcut hands off.
The boundary is what dtop does not do. It does not schedule, does not roll out versions, does not manage networks or volumes, and has no cluster view. For a fleet of plain Docker hosts that a team already drives by hand, that is exactly the right size of tool.
Editorial conclusion
Adopt dtop if your team runs Docker on more than one machine and wants a single screen instead of a fleet of SSH sessions, and if you already run Dozzle for logs. Do not expect it to replace your orchestrator: container start, stop and remove are exposed, but scheduling, rolling updates and cluster awareness are not, and Kubernetes support is an unchecked box on the roadmap. Check three things before you wire it into a routine. Confirm that the transport you need is permitted, since an SSH host needs the openssh transport and a TLS host needs DOCKER_CERT_PATH holding key.pem, cert.pem and ca.pem. Confirm that the version you install can update itself, because dtop update only works for binaries from the install script or a GitHub release, while Homebrew, Docker and cargo installs have their own path. And confirm that the filters you rely on behave as documented, since the project notes that some filters only apply to container listing and not to events. The last push was on 2026-10-17, with v0.10.2 released on 2026-10-15, under the MIT license.
Frequently asked questions
How do I install dtop on macOS or Linux?
The recommended route is Homebrew, which the project marks as recommended for macOS and Linux because it upgrades dtop automatically. The install script, a Docker image, Nix and cargo install are also documented.
How do I monitor a remote Docker host with dtop?
Pass the host with the --host flag, which can be repeated to cover several hosts. Supported forms include ssh://user@host, ssh://user@host:2222, tcp://host:2375, tls://host:2376 and unix:///path/docker.sock, alongside local for the active Docker context.
Does dtop support TLS connections to a Docker daemon?
Yes, through the tls://host:2376 form of the --host flag. Set DOCKER_CERT_PATH to a directory containing key.pem, cert.pem and ca.pem, and note that a custom SSH transport was written for bollard so that ssh:// URLs with explicit ports are honoured.
How do I update dtop after installing it?
The dtop update command checks GitHub releases and replaces the binary, but only for binaries from the install script or a GitHub release download. Homebrew installs upgrade through brew, Docker images need a new pull, and cargo installs need cargo install dtop --force.
Does dtop work with Kubernetes?
Not yet. Support for Kubernetes clusters is the one unchecked item on the project roadmap, so dtop currently monitors Docker daemons reached over a socket, SSH, TCP or TLS rather than cluster workloads.
What license is dtop released under?
The MIT license, as declared in Cargo.toml and published as a LICENSE file at the root of the repository. The crate metadata lists edition 2024 and a minimum Rust version of 1.98.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/amir20-dtop)Was this useful?