Skip to content

One binary.
Every container. Full control.

Docker Commander is a self-hosted monitoring and control panel for Docker — live stats and logs, Compose, alerting and per-user permissions across every host you run. No external database, no agents, no cloud account.

  • Single Go binary
  • No external database
  • No agents
  • Linux · macOS · Windows
  • MIT licensed
quick start — macOS / Linux
brew install koduj-dev/tap/dockercmd
dockercmd

Prefer Docker, a raw binary or go install? All four are below.

  • CI status
  • Latest release
  • Go version
  • License MIT
  • Container image on GHCR
127.0.0.1:8470
The Docker Commander dashboard: host facts, disk usage, a per-container resource breakdown and the running containers, with live CPU and memory graphs.

Why bother

What it actually saves you

There is no shortage of Docker dashboards. These are the four things that tend to decide it.

One binary, zero infrastructure

Download one CGO-free executable with the web UI compiled into it and run it. No database server to provision, no agent to install on each host, no reverse-proxy prerequisite. State goes in an embedded SQLite file inside the data directory. It listens on 127.0.0.1:8470 and that is the whole install.

See it and fix it in the same place

Most dashboards stop at read-only. Here the container that just spiked is one click from its logs, a shell, its files, its limits and a restart — so diagnosing and acting are not two different tools.

Built to sit on a real server

Argon2id passwords, TOTP 2FA or passkeys, named roles that can be scoped to specific hosts, read-only accounts, an audit log, secrets encrypted at rest and native HTTPS. Local-only by default, so exposing it is a deliberate step you take.

Your hosts, your data

Self-hosted and MIT licensed. No account, no cloud tenant, no telemetry: the only request it makes on its own is the update check against GitHub Releases. Everything else it talks to is something you configured.

Author’s note

Why I built Docker Commander

Docker Commander grew out of two very practical needs.

First, I wanted a simpler way to keep my own Docker hosts under control. When something went wrong, I was tired of jumping between SSH sessions, docker stats, logs, Compose files and several tools that each solved only one part of the problem. I wanted one place where I could see what was happening, investigate it and act immediately.

The second reason came from teaching. At the university, students need to work with real containers, images, networks, volumes and Compose projects — but too much of the lesson can easily disappear into fighting the command line, permissions and configuration details instead of understanding how Docker actually works.

The goal was never to hide Docker behind a simplified toy interface. Docker Commander exposes the real objects and operations, but makes them easier to discover, inspect and control. Students can see how the pieces fit together, while experienced users can still reach the logs, shell, files, raw configuration and lifecycle controls they need.

What began as a small helper for my own servers and university classes gradually became a broader open-source project. The original principle has remained the same: infrastructure tooling should remove unnecessary complexity, not introduce another stack that needs to be maintained.

Portrait of Filip Majerík

Built by

Filip Majerík

Software developer & university lecturer

Filip Majerík is a software developer, university lecturer and long-time builder of web-based systems. Docker Commander is developed under his direction, shaped by practical infrastructure work, classroom experience and an unreasonable number of occasions spent explaining bind mounts.

He reviews the architecture, behavior and security-sensitive parts of the project, while using AI-assisted development extensively for implementation, testing and documentation.

How much of this was written with AI, and what that does and does not mean, is spelled out further down — and every line of it is public in the repository.

Who it is for

Find yourself in one of these

The same binary serves a single NAS and a small fleet — what changes is which half of the feature set you end up living in.

Homelab & self-hosters

A dozen containers on a NAS or a mini-PC, plus a laptop that is offline half the time. Add hosts over SSH, disable the ones that sleep, and get an email when something crash-loops.

  • Agentless SSH hosts
  • Disable offline hosts
  • Email & webhook alerts

Small dev teams

Staging and production on a few VPS boxes, with people who need different amounts of access. Give reviewers read-only, scope an operator to staging only, and keep an audit trail of who did what.

  • Named roles, scoped per host
  • Read-only accounts
  • Audit log
  • LDAP / AD login

Ops & on-call

When something is on fire at 03:00 you want aggregated logs with regex, live CPU and memory history, and a shell — from a phone-friendly UI rather than three SSH sessions.

  • Aggregated logs + regex
  • Historical charts
  • Prometheus /metrics
  • In-browser shell

Teaching & labs

Students meet real containers, images, networks, volumes and Compose projects through an interface that shows the Docker model rather than hiding it — so a lesson is spent on how Docker works, not on shell quoting and file permissions.

  • Real Docker objects, not abstractions
  • Relationships visible in the topology graph
  • Read-only accounts for lab hosts
  • Complements the CLI — it does not replace it

AI-assisted workflows

Let Claude Code, Claude Desktop or Cursor read your container state and perform safe restarts and deploys through an opt-in MCP server that reuses your own permissions.

  • Off by default
  • Bearer token or OAuth 2.1
  • Tokens can only narrow rights
  • Changes rate limited & audited

Features

Everything it does, grouped

Eight areas, all in the same binary. Nothing here is reserved for a paid tier — there isn't one.

Monitor

Live and historical, across every host you have added.

  • Live CPU and memory graphs over WebSockets, plus historical charts (Redis or in-memory).
  • A dashboard driven by the Docker events stream: host facts, disk usage, per-container share of host CPU and memory, host-wide network throughput, and a port scan that fingerprints what is actually listening.
  • Per-container network throughput (derived rate, so a recreate reads as a gap rather than a spike), totals, packets, dropped and errors, plus endpoint totals on a network’s own detail page.
  • Per-container log tail and a global aggregated stream with level detection, regex search and saved parsing rules that turn lines into structured columns.
  • Events feed, container diff and top, disk usage, and raw JSON inspect for any object.
  • Interactive containers-and-networks topology graph with search and compose-stack filtering, plus a compact list view.

Control

Full lifecycle, not a read-only window.

  • Create and run containers, start / stop / restart / pause / unpause / kill, rename, update limits and restart policy, commit to an image, and open an interactive shell (xterm.js). Kill goes through its own confirm — it is SIGKILL for a container that stopped responding to Stop.
  • Bulk restart, stop, start and pull across several selected containers at once: a preview of exactly what is targeted, the same confirm dialog, bounded parallelism, and a per-container success/failure summary instead of one toast for the batch.
  • File browser inside containers and volumes — list, download, upload, upload-and-extract a .zip / .tar / .tar.gz, delete, create folders.
  • Images: pull with live progress, build (with build args), push, tag, save / load / import, history, prune, and vulnerability scanning via Trivy with a severity summary and CVE table.
  • Volumes and networks: list, inspect, create, remove, prune — networks also connect and disconnect containers.

Compose

Discovered stacks and managed projects, edited in place.

  • Discover and manage stacks by label — including ones created from the CLI: start, stop, restart, remove, and now edit the compose file in place on the host and redeploy, kept in its original working directory so relative bind mounts and env_file paths still resolve.
  • Managed project folders edited in a built-in CodeMirror editor with live inline validation: compose (anchor and ${VAR} aware), Dockerfile via docker build --check, YAML / JSON / .env.
  • Resolved preview, services and ports summary, templates, schema-aware Compose autocomplete, and image or tag suggestions from local images, Docker Hub and your private registries.
  • Deploy through the docker compose CLI with profiles and .zip import / export — to the local daemon or a remote host, where each bind mount inside the project folder is copied into a named volume on the target and mounts outside it are refused unless the project opts into host paths.
  • Moving a project to another host offers to bring it down on the one it is leaving, so a redeploy never leaves two live copies running.

Multi-host

Agentless. Local, TCP+TLS or SSH.

  • Manage local, TCP(+TLS) and SSH daemons — no agent to deploy, it speaks the Docker Engine API.
  • SSH host keys are verified against known_hosts with trust-on-first-use; a changed key is refused as a possible MITM.
  • Every view rebinds to the selected host and the alert engine watches all of them.
  • A per-host detail panel shows hardware, OS and engine, and a host can be disabled to take it out of monitoring.
  • Roles can be scoped to specific hosts, so “may restart containers” can mean “on staging, not production” — a host outside that scope is invisible, not just blocked.

Alerting & integrations

Rules that reach you where you already look.

  • Rules on state (die, kill, oom, unhealthy), resource thresholds sustained over N seconds, log patterns, and restart or crash-loop frequency.
  • Editable severity and cooldown, targeting containers by name substring.
  • Conditions have a lifetime — firing, escalated, eased, resolved — so overlapping thresholds produce one incident instead of one alert each.
  • Notify via webhooks with Go-template bodies, email over SMTP with per-rule and per-account recipients, and an in-app feed with a toast on arrival.
  • Every webhook call and e-mail send is recorded against its alert with the outcome, so a delivery failure shows instead of looking silently handled.
  • The feed is paged, filtered and sorted server-side, with acknowledgement history. A Prometheus /metrics exporter includes live firing conditions, and alert rules import and export as a portable JSON bundle.

Security & administration

Multi-user with real boundaries.

  • Argon2id passwords with TOTP 2FA or passkeys (WebAuthn) — a verified passkey can sign in on its own, with the password kept as the recovery route. Rate limiting, strict headers and signed HttpOnly cookies.
  • An account can hold several authenticators, named and listed with last use; TOTP codes and rate limiting on the 2FA step guard against replay and brute-force alike.
  • Every account can see its own live sessions — device, address, last used — and end any of them, or all the others at once.
  • Named RBAC roles bundle section grants (two ship built in, or duplicate and edit your own), and a role can be scoped to specific hosts. Read-only mode, global feature flags and an audit log sit alongside.
  • Optional LDAP / Active Directory login with auto-provisioning; a directory group can grant a named role, not just raw sections, re-derived on every login.
  • Registry, SMTP and LDAP secrets — and host TLS private keys — encrypted at rest with AES-256-GCM.
  • dockercmd --backup / --restore snapshots the whole installation to one portable, optionally passphrase-encrypted file — and dockercmd --reset-password recovers a locked-out admin without stopping the server.

AI tools over MCP

Opt-in, and narrower than your own account.

  • An off-by-default Model Context Protocol server lets Claude Code, Claude Desktop and Cursor monitor and safely operate Docker as you.
  • Around 25 read tools — including diagnostics that don’t need a shell (docker top / diff, cross-container log search) and the alerting surface (history, what’s firing now, rules, delivery) — plus safe control: start/stop/restart a container or a whole stack, deploy/down a project (including to a remote host), preview what a deploy would change, and a Trivy image scan.
  • Bearer API tokens or OAuth 2.1 with PKCE and dynamic client registration; every call reuses the app’s RBAC and a token can only narrow your sections, hosts and rights.
  • New tokens expire after 30 days by default (admin-configurable), and changes are rate limited per user so a stuck loop or a stolen token is bounded to a few containers rather than the whole estate.
  • Deliberately no exec, image export, file read, prune or remove.

Ops

Boring to run, on purpose.

  • Single CGO-free binary with the UI embedded, a systemd unit, a config file, and a /healthz probe.
  • Native HTTPS with a built-in --make-certs self-signed helper, or run it behind a proxy.
  • Self-install as a service on Linux (systemd) and macOS (launchd); a PowerShell script covers Windows.
  • One-tap in-app update and restart for admins, plus dockercmd --self-upgrade with SHA-256 verification and an atomic binary replace.
  • A portable, encryptable backup/restore snapshot of the whole installation — database, projects and templates — safe to take while the server is running.

A per-feature user manual — one page per screen — lives in the docs folder.

Screenshots

The whole interface, nothing staged

All 23 screens are captures of the running app. Filter by area, or click any one to enlarge.

Install

Running in under a minute

Pick a route. All four end at http://127.0.0.1:8470, where you create the admin account and scan a QR code for 2FA. Needs Docker Engine 24 or newer (API 1.43+).

Multi-arch (amd64/arm64), distroless, non-root, read-only root filesystem.

Docker — shell
docker run -d --name dockercmd \
  -p 127.0.0.1:8470:8470 \
  --group-add "$(stat -c '%g' /var/run/docker.sock)" \
  --read-only --tmpfs /tmp \
  --security-opt no-new-privileges \
  --cap-drop ALL \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockercmd-data:/data \
  ghcr.io/koduj-dev/docker-commander:latest

On rootless Docker or Docker Desktop the socket is owned by your user — drop the --group-add line. In production, pin an immutable @sha256 digest instead of :latest.

macOS and Linux. Installs the signed release binary for your OS and architecture.

Homebrew — shell
brew install koduj-dev/tap/dockercmd
dockercmd --version

Grab your OS and architecture from the Releases page. Debian/Ubuntu and Fedora users can take a .deb or .rpm, which sets up the systemd service.

Binary — shell
chmod +x dockercmd-linux-amd64
./dockercmd-linux-amd64          # http://127.0.0.1:8470

sudo ./dockercmd-linux-amd64 --install-service   # optional: run it 24/7

On Windows, run dockercmd-windows-amd64.exe from a terminal.

Needs Go ≥ 1.25 and Node.js ≥ 18 to build the UI, plus a running Docker daemon.

From source — shell
git clone https://github.com/koduj-dev/docker-commander.git
cd docker-commander
make build      # builds the UI, then embeds it in the binary
./dockercmd     # http://127.0.0.1:8470

Or, without the UI build step: go install github.com/koduj-dev/docker-commander/cmd/dockercmd@latest

Compatibility

Tested against real Docker, not assumed

Most tools just claim a version floor. A nightly job instead points the whole Docker integration suite at a pinned build of each Engine major below and reports what actually happens — so this list is a live result, not a guess.

  • Engine 24.x
  • Engine 25.x
  • Engine 26.x
  • Engine 27.x
  • Engine 28.x

Minimum Engine API 1.43 (Engine 24) · docker compose plugin v2 or newer — legacy docker-compose v1 is not supported · the client SDK negotiates down to whatever your daemon speaks, so a newer build talks to an older one without any configuration.

See tonight's run

AI tools over MCP

Let an assistant watch your containers — safely

An optional Model Context Protocol server exposes Docker Commander to Claude Code, Claude Desktop and Cursor. It was designed around what an AI agent should not be able to do.

  • Off unless you turn it on

    The server is not mounted at all without DC_MCP_ENABLED — the routes return a bare 404. Nothing to opt out of.

  • Two ways to authenticate

    A bearer API token from a self-service page, or OAuth 2.1 with PKCE and dynamic client registration for Claude Desktop and Cursor.

  • A token can only narrow your rights

    Every call reuses the app’s RBAC. A token may be restricted to a subset of sections, a subset of hosts, and made read-only — it can never widen what your account can do.

  • Dangerous verbs are simply absent

    No exec or shell, no image export, no file reads, no prune, no remove. Not gated behind a flag — not implemented in the MCP surface.

  • A ceiling on how fast it can act

    Changes are capped per user per minute, so a model stuck in a loop — or a stolen token — is bounded to a few containers rather than your whole estate. Reads are not throttled; only writes are.

Around 25 read tools — including diagnostics and the alerting surface — plus safe control: start, stop, restart a container or a whole stack, deploy or down a project, and a Trivy scan. With MCP resources and prompts. Point Claude Code at it:

enable, then connect
# on the server
dockercmd -mcp-enabled -mcp-public-url https://docker.example.com

# on your machine
claude mcp add --transport http docker-commander \
  https://docker.example.com/mcp \
  --header "Authorization: Bearer <your-token>"
Read the MCP documentation
127.0.0.1:8470/settings/mcp
The MCP access page: issuing a bearer token for an AI tool, scoped to a subset of sections and optionally read-only.

The OAuth server is self-contained (RFC 8414 / 7591 / 8707, PKCE S256, audience-bound and client-bound JWTs, rotating refresh — revoking a client takes effect immediately, not at token expiry) and was exercised with adversarial security tests — alg=none, code and refresh replay, redirect smuggling, CSRF, IDOR.

Security & supply chain

A panel that controls your host should earn it

Two separate questions: can you trust the binary you downloaded, and can you trust it once it is running. Both have concrete answers — but neither changes what mounting the Docker socket grants, which is a deployment decision rather than an application one.

Verify what you downloaded

Every release ships checksums, a keyless cosign signature bundle covering the binaries and an SPDX SBOM, plus per-binary build provenance. The container image is signed and carries SLSA provenance as well. Three commands prove the artifact came from the release workflow in this repository and nowhere else.

  1. 01

    Checksums

    Every release ships SHA256SUMS covering the binaries and the SPDX SBOM.

  2. 02

    Keyless signature

    A cosign bundle signs those checksums, tied to the release workflow identity. Needs cosign v3+.

  3. 03

    Build provenance

    Each binary and the container image carry SLSA provenance attestations.

verify a release — copy all three
# 1. Checksums
sha256sum -c SHA256SUMS --ignore-missing

# 2. Keyless signature
cosign verify-blob --bundle SHA256SUMS.bundle \
  --certificate-identity-regexp '^https://github\.com/koduj-dev/docker-commander/\.github/workflows/release\.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMS

# 3. Build provenance
gh attestation verify dockercmd-linux-amd64 --repo koduj-dev/docker-commander

And once it is running

Authentication

  • Argon2id password hashing
  • TOTP 2FA or passkeys (WebAuthn), several per account
  • Passwordless sign-in with a verified passkey, off until you opt in
  • Signed HttpOnly cookies, rate limiting, strict headers
  • Optional LDAP / Active Directory with group → role mapping

Authorization

  • Named RBAC roles, scoped to specific hosts
  • Read-only accounts and global feature flags
  • An audit log of who did what, where
  • MCP tokens can only narrow an account’s sections, hosts and rights

Secrets at rest

  • Registry, SMTP and LDAP credentials encrypted with AES-256-GCM
  • Host TLS private keys encrypted too
  • Keys generated on first run, kept in the data dir
  • Stored secrets are never returned by the API

Transport

  • Binds 127.0.0.1 by default — exposure is a deliberate act
  • Native HTTPS, or a --make-certs self-signed helper
  • SSH daemon host keys verified (known_hosts / trust-on-first-use)
  • A changed SSH host key is refused as a possible MITM
Report a vulnerability privatelyVerifying the bundle needs cosign v3+; releases up to v1.5.0 use the older signature pair.

Releases

Straight from GitHub

Read straight from the repository's releases API, then summarised automatically: each entry keeps the pull-request titles GitHub generated, minus the dependency bumps and release chores. Nothing here is hand-written — for the full text, follow through to the release notes.

v1.6.2
Latest version
yesterday
Released
16
Releases
2 hours ago
Last commit
MIT
License

Built from the koduj-dev/docker-commander releases API

All releases
  1. v1.6.2Latest · 1 hour ago
    • Change[docs] note the per-PR ChatGPT Codex review pass in testing.md
    • Change[fix] self-update: allow the systemd unit to write /usr/local/bin
    13 downloadable assetsRelease notes
  2. v1.6.1 · 2 hours ago
    • Change[docs] roadmap: backup/DR, drift detection, GitOps, federation, secrets
    • Change[docs] release/vX.Y.Z branch holds the dev cycle, not main
    • Change[docs] dependabot PRs stay targeted at main
    +23 more changes13 downloadable assetsRelease notes
  3. v1.6.0 · last week
    • Newprojects: Ship bind-mounted files on a remote deploy
    • Newprojects: Close out the remote-projects follow-ups
    • Newsecurity: Named RBAC roles (phase 1)
    +82 more changes13 downloadable assetsRelease notes
  4. v1.5.1 · 2 weeks ago
    • DocsBring README features + NEXT.md roadmap up to v1.5
    • Docsrelease: Cut 1.5.1
    +3 more changes13 downloadable assetsRelease notes
  5. v1.5.0 · 2 months ago
    • Newtls: Built-in self-signed cert generator (--make-certs)
    • Newalerts: Import/export alert rules as a portable JSON bundle
    • Newupdate: One-tap in-app update & restart for admins
    +10 more changes14 downloadable assetsRelease notes

Prefer the long form? The changelog follows Keep a Changelog, and the roadmap records what is shipped versus merely intended.

Comparison

How it differs from the usual suspects

All four are good tools and several of them overlap — this is where Docker Commander is deliberately different. Compiled from each project's public documentation in August 2026.

Feature comparison between Docker Commander, Portainer CE, Dozzle and Lazydocker
CapabilityDocker CommanderPortainer CEDozzleLazydocker
InterfaceWeb UIWeb UIWeb UITerminal UI
ScopeMonitor + full controlMonitor + full controlMonitor + optional controlStart/stop/restart/update are opt-in and role-gated, off by defaultMonitor + control
Runtime dependenciesOne binary, embedded SQLiteContainer with embedded DBOne binaryOne CLI binary
Multi-hostYesAgentless — TCP+TLS or SSHYesVia an agent per hostYesVia an agent per hostNot built inLocal daemon only
Two-factor / passwordless loginYesTOTP or WebAuthn passkeys, enforced by defaultNot built inPassword (+ LDAP/OAuth) — no 2FA documentedNot built inLogin itself is optional and off by default; no 2FANot built inNo login — local socket only, no network auth
Aggregated logs across containersYesLevel detection, regex, parse rulesNot built inPer containerYesIts whole purposeNot built inPer container
Built-in alert rules → webhook / emailYesState, resource, log-pattern, crash-loop → webhook & e-mailNot built inPartiallyLog, metric & event alerts → webhook/Slack/Discord/ntfy, no e-mailNot built in
Prometheus exporterYesNot built inNot built inNot built in
Compose editing in the UIYesValidated editor + templatesPartiallyStack definitionsNot built inNot built in
MCP server for AI assistantsYesOff by default, RBAC-scoped, read + safe controlNot built inPartiallyOff by default, read-only (no control tools)Not built in
Image vulnerability scanningYesTrivy, in-appNot built inNot built inNot built in
Sources

A cross has one meaning here: not documented as a built-in feature in the source above. Several of these projects cover the same ground through plugins, agents or a paid edition.

Roadmap

What is being considered next

Ideas, not promises — none of these has a date. The project's notes are deliberate about separating what shipped from what is merely intended.

  • Deployment revisions and rollback

    An immutable history of every deploy — compose file, resolved config, image digests, who and why — with diff, preview and restore. The highest-value item on the list: today you can change a deployment, but not undo one.

  • Maintenance windows and silences

    Suppress notifications during planned work without turning monitoring off, scoped by host, stack, container, rule or severity — the alert is still recorded, just not paged.

  • Policy checks before deploy

    Refuse or warn on privileged containers, host network or PID, a mounted Docker socket, :latest in production, or missing resource limits and healthchecks — tying validation, linting and scanning that already exist to an actual decision.

  • OIDC / SSO

    Google, Azure and Okta login. LDAP — including group → role mapping — was step one.

  • ACME / Let’s Encrypt

    Self-signed certificates ship today; still open is automatic issuance and renewal for a public hostname.

  • Windows native service

    The binary installs itself as a systemd unit on Linux and a launchd agent on macOS; Windows currently goes through a Scheduled Task script rather than a real SCM-managed service.

FAQ

The questions that actually get asked

Including the awkward ones.

Do I need a database or an agent?

Neither. State lives in an embedded SQLite file (pure Go, no CGO) inside the data directory, and remote hosts are reached over the Docker Engine API via TCP+TLS or SSH — there is nothing to install on them. Redis is optional, and only to keep metric history across restarts; without it history sits in an in-memory ring.

Is it safe to expose on the internet?

Treat it as you would any panel that can control your host. It binds to 127.0.0.1:8470 by default; TOTP 2FA or a passkey is enforced unless an admin turns on the localhost exemption — which only ever applies to an actual direct loopback connection, never one arriving through a reverse proxy, however it presents itself. There are named roles that can be scoped to specific hosts, read-only accounts, rate limiting, an audit log, and your own live sessions are visible and revocable from your profile. If you publish it, terminate TLS at a reverse proxy or use the built-in HTTPS, and keep that localhost exemption off.

What does mounting the Docker socket actually give away?

Host-root-equivalent access. Anyone who reaches the UI — or escapes the app — controls the daemon, and therefore the machine. That is true of every Docker management tool, so the honest advice is: keep it on localhost or behind HTTPS with strong auth, and never expose it unauthenticated.

Is this affiliated with Docker, Inc.?

No. It is an independent open-source project with no affiliation, sponsorship or endorsement from Docker, Inc. It talks to the Docker Engine API like any other client. "Docker" is a trademark of Docker, Inc.

How much of it was written by AI?

Roughly 95% — code, tests and docs — using Claude Code, under human direction and review. Every release goes through CI on top of roughly 600 Go unit tests, 147 frontend tests and 115 adversarial "pentest" cases that assert attacks are rejected (token forgery, CSRF, IDOR, path traversal, per-host scope bypass), plus integration and multi-daemon tests against real Docker hosts. The tree is also periodically swept by an independent adversarial review on Claude Fable 5 — not an independent third-party audit or penetration test.

Does it phone home?

No telemetry, no analytics. The only automatic outbound request is the update check against GitHub Releases, which is what puts the "update available" banner in front of an admin; and otherwise only talks to whatever you configure yourself — your Docker hosts, your SMTP server, your webhooks, your registries.

Will it fight with my existing setup?

No. It reads and writes through the Docker API like the CLI does, so containers and stacks you created elsewhere show up and stay manageable — compose stacks are discovered by label whether they came from this UI or from docker compose in a terminal. Stop using it and nothing needs unwinding.

Where does my data live, and how do I back it up?

Everything is in one data directory: the SQLite database plus the signing and at-rest encryption keys, generated on first run. It defaults to the OS config dir and moves with -data-dir / DC_DATA_DIR; under Docker it is the /data volume. dockercmd --backup <file> writes a complete, portable snapshot — the database plus your projects and templates — through a live connection, so it is safe to run while the server is up; --restore <file> puts it back, and --passphrase encrypts the archive. Treat a backup as secret: it holds the key that decrypts your registry, SMTP and LDAP credentials, and losing an unencrypted copy makes them recoverable by whoever has it.

How do I upgrade?

An admin sees an "update available" banner and can apply it in place — one tap to update and restart. From a shell it is dockercmd --self-upgrade, which verifies the SHA-256 and swaps the binary atomically. Running the container image, pull the new tag instead; installed from a .deb or .rpm, use your package manager. The data directory is untouched either way, so an upgrade is not a migration.

Which platforms are supported?

Release binaries cover linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64 and windows/arm64, plus .deb and .rpm packages and a multi-arch container image. The binary can install itself as a systemd unit on Linux or a launchd agent on macOS.

Which Docker version do I need?

Engine API 1.43 or newer — that is Docker Engine 24 and up — and the docker compose CLI plugin v2 or newer (the legacy docker-compose v1 is not supported). The client SDK negotiates down to whatever your daemon speaks, so a newer build talks to an older engine without any configuration. This is not a guess: a nightly workflow runs the full Docker integration suite against Engine 24 through 28 and reports the result, so the floor is measured rather than remembered.

What is the license?

MIT. Use it commercially, fork it, ship it inside something else — no feature is held back for a paid tier, because there is no paid tier.

Something not answered here? Ask in the issue tracker — questions are welcome, not just bug reports.

Not a Docker, Inc. product

Docker Commander is an independent open-source project, developed with no affiliation to Docker, Inc. — no support, no sponsorship, no endorsement. It is not part of Docker Desktop, Docker Hub or any commercial Docker offering, and no one at Docker, Inc. reviews or approves it.

It is a third-party client of the public Docker Engine API — the same interface the docker CLI uses. “Docker” and the Docker logo are trademarks or registered trademarks of Docker, Inc., used here only to describe what this software works with.

If you represent Docker, Inc. and consider any use of the marks on this page or in the project inappropriate, please open an issue and it will be corrected.

Roughly 95% written by AI

Code, tests and documentation were largely produced with Claude Code, under human direction and review. This is stated up front because you are about to give this software control of your Docker daemon, and that is a decision you should make knowingly.

What that does not mean is unreviewed output. Every change goes through CI on top of roughly 600 Go unit tests and 147 frontend tests, 115 adversarial "pentest" cases that assert attacks are rejected, and integration tests against a real daemon. The tree is also periodically swept by an independent adversarial review on Claude Fable 5.

  • Human-directed and human-reviewed, not autonomous
  • CI, unit and integration tests on every release
  • 115 adversarial "pentest" cases across auth, deploy and RBAC
  • Read it yourself — all of it is public at koduj-dev/docker-commander

Docker Commander is provided under the MIT license, “as is”, without warranty of any kind. You are responsible for how you deploy it and for what it is allowed to reach — see the note about the Docker socket in the install section.

Support the project

Free, and staying that way

Docker Commander is MIT licensed with no paid tier and nothing held back. If it saves you time, there are three ways to help — two of them free.

Star the repository

Costs nothing and is the signal other people actually use when deciding whether a self-hosted tool is alive.

Star on GitHub

Report or contribute

A precise bug report is worth more than most patches. Feature requests and pull requests are read and answered.

Open an issue

Sponsor the project

Through GitHub Sponsors, one-off or monthly. It covers the domain, the signing infrastructure and the hours — it does not buy the software, which is free either way.

Sponsor on GitHub

Sponsoring buys nothing, because there is nothing to buy: Docker Commander is MIT licensed, every feature ships in the public release, and no capability will ever sit behind a paywall. A sponsorship supports the person maintaining it — it carries no support commitment, no priority and no influence over the roadmap, and it is not a tax-deductible donation.

Try it on one host tonight

It is one binary and a named volume. If you do not like it, delete both — nothing on your Docker hosts was changed to accommodate it.

Docker Commander v1.6.2 — Docker, hardened
docker run -d --name dockercmd \
  -p 127.0.0.1:8470:8470 \
  --group-add "$(stat -c '%g' /var/run/docker.sock)" \
  --read-only --tmpfs /tmp \
  --security-opt no-new-privileges \
  --cap-drop ALL \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockercmd-data:/data \
  ghcr.io/koduj-dev/docker-commander:latest

Read-only root filesystem, no added capabilities, no privilege escalation, bound to localhost. On rootless Docker or Docker Desktop, drop the --group-add line.

Show the minimal command
Docker — minimal
docker run -d --name dockercmd -p 127.0.0.1:8470:8470 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockercmd-data:/data \
  ghcr.io/koduj-dev/docker-commander:latest

Fewer flags, and correspondingly fewer guardrails. Fine for a throwaway look on a machine you do not mind losing; the hardened form above is what belongs on anything you keep.

MIT licensed · no account · no telemetry · Linux, macOS and Windows