MangoDock · Self-hosted · One container
Docker management
with nothing on the hosts.
A server you run and a browser UI. MangoDock reaches each daemon over an ordinary SSH session — no agent to install, no port to open. If you can SSH to a box, you can manage it.
Two editions
One image. Two ways in.
MangoDock makes no outbound request of its own in either edition — no telemetry, no update check, no third-party fonts or scripts in the page, and its vulnerability scanners are told not to phone home. So the editions are not two different programs with different features. They differ only in how the software and its databases reach the network you are running it on.
Internet
- Install with one docker run, or the included Compose file.
- Scanners fetch their own vulnerability databases, and their age is shown.
- Update checks ask the registries directly.
- Upgrading is a pull and a restart; the data volume is untouched.
Air-gapped
- One bundle is built on a machine that has internet, carried across as a single file, and unpacked on the other side.
- It carries the image, its helper image, fresh Trivy and Grype databases, a Compose file pinned to that version with pulls disabled, an installer and a SHA256SUMS file.
- The installer refuses to continue if any file fails its checksum — nothing is loaded until every hash matches.
- It installs the databases with scanning set to Offline and starts on a port you choose, with the local Docker socket optional.
Inside the enclave
- Point it at your own registry — Map docker.io, ghcr.io or quay.io to an internal proxy cache. Every pull then goes through the mirror and keeps the original image name, update checks ask the mirror, and stack deploys pre-pull through it.
- Keep the scanners current by hand — Import database archives from a newer bundle, or export them straight from a connected MangoDock. If your registry hosts them, point at it as an internal mirror instead.
- Stale beats refused — Offline, the vulnerability databases are used however old they get rather than rejected outright — and their age is shown, so you know what you are trusting.
- A check never hangs on the gap — An update check against a registry the network cannot reach gives up after fifteen seconds and skips that registry's other images for the rest of the run.
- Upgrades stay offline — Unpack the newer bundle and run its installer. The data volume is kept, so accounts, hosts and stacks survive.
Differences
Built the other way round
Most of what separates MangoDock is a decision taken once, early, and then never walked back. Here is each of them, and what the usual answer is.
Nothing is installed on the host
The common answer is an agent on every machine you want to manage, or the Docker API published on a TCP port.
MangoDock reaches the daemon over an ordinary SSH session — a direct-streamlocal channel to the remote socket. A host you can already SSH to is a host you can already manage: nothing to install, nothing to open, nothing to uninstall later.
Five ways in, not one
A tool usually supports the one transport it was designed around, and the rest of your estate has to be bent to fit it.
SSH, a local socket, a local pipe, TCP with mutual TLS, or plain TCP. All five are first-class; what differs is what each asks of the host and what each is worth trusting, which the page says out loud rather than leaving you to find out.
Authentication is not optional
Many self-hosted Docker UIs ship with authentication off until somebody turns it on — and the honest reading of that default is that plenty of installs never do.
The first request against a fresh install is “create the admin account”, and no environment variable disables it. Three roles are checked in the route handler, so a crafted request is refused exactly like a hidden button.
Mature tools do their own jobs
Reimplementing Compose, git and CVE scanning inside the product is how a management tool ends up subtly disagreeing with the ecosystem it manages.
Compose deploys are real docker compose. GitOps is real git. Scanning is real Trivy or Grype. MangoDock shells out and reads back what they print, so what you get is what those tools would have done on the host themselves.
Backups do not travel through the tool
Pulling a volume through the control plane makes the management server the bottleneck, and makes its bandwidth your restore time.
A helper container on the host that owns the volume pushes straight to your destination; MangoDock only ever sees the exit code. The repository format is restic's, so a backup can be restored by somebody who no longer runs MangoDock.
Disconnected is a supported state
Air-gapped support is usually a documentation page about proxies, and the scanners quietly stop working once their databases go stale.
One bundle, built by the image itself, carries the images and fresh vulnerability databases across. Offline, a database is used however old it is and its age is shown — stale beats refusing to scan at all.
It fails loudly or not at all
Both popular scanners fall back to pulling a public image when they cannot reach the daemon, which turns an unreachable host into a clean report on somebody else's image.
MangoDock pins the image source on both so that failure is loud. The same instinct elsewhere: a stack deploy on a CLI-only transport says the Engine API is required instead of half-working.
The database is a choice, not a surprise
A tool that only speaks SQLite becomes a migration problem on the day the team outgrows it.
SQLite by default, in the same volume, with nothing to configure. Point MANGODOCK_DATABASE_URL at Postgres and it uses Postgres — every migration is written dialect-neutral for exactly that.
Transports
Five ways to reach a daemon
All five are supported. What differs is what each one asks of the host, and what each is worth trusting.
1 of 5
SSH
ssh://user@hostAuthorisation is the SSH identity and group membership the host already trusts.
Host preparation: Nothing
Features
Everything the daemon can do, in one place
Containers, Compose stacks, GitOps deploys, scheduled redeploys and image scanning — with accounts and an audit trail from the first install.
Hosts
- One card per Docker host, with running, stopped, paused and unhealthy counts
- CPU and memory gauges plus a history sparkline, not just a number now
- Disk usage split across images, containers and volumes
- Object counts for images, stacks, volumes and networks
- Top containers by CPU, and a recent events feed
- Switch host from the top bar; its facts follow the selection
Containers
- The full lifecycle — create, start, stop, restart, remove
- Live logs, live stats and a live event stream
- An interactive terminal into a running container
- An environment-variable dialog rather than hand-edited JSON
- Update checking, so a stale image is visible before it bites
- Verified against a real daemon, not a mock
Stacks
- Compose projects grouped automatically from labels already on each container
- The dependency graph drawn from those same labels
- Bulk start, stop and restart for a whole stack
- Deploy and tear down with the real docker compose CLI, not a reimplementation
- A visual editor that builds services and dependencies on that graph
- Saves its own definition and generates deploy YAML from it
GitOps & schedules
- Deploy a stack straight from a git repository
- A private repo's access token is injected per request, never written to disk
- An inbound webhook redeploys on push, authenticated by a token in its own URL
- A cron scheduler redeploys a saved stack with no request from anyone
- A git-backed stack opens its compose file from the repository, naming the commit
- Graceful shutdown, so a redeploy in flight is not abandoned
Logs, console & events
- Logs and Console are first-class pages, not buried in a container detail view
- They sit in the everyday half of the sidebar — the two "something is wrong" tools
- An activity feed with relative timestamps and its own filters
- A live-connection indicator, so a stalled stream is obvious
- The connection kind is shown in the top bar, because it decides what is possible
- Console is hidden from viewers, whose shell upgrade the server refuses anyway
Images & scanning
- Vulnerability scanning with the real trivy CLI
- Scanned through the same proxy a deploy uses, so the image is checked as it exists on that daemon
- A severity column right on the Images page
- A findings view with CVE identifiers linking to the real advisory
- SARIF export, for whatever already consumes your scan output
- Registry, volumes and networks each keep their own page
Accounts & access
- Accounts and sessions are mandatory on every install — no toggle, no anonymous access
- Three roles enforced on the server, not hidden in the UI: admin, operator, viewer
- Single sign-on over OpenID Connect
- Sign in against a real LDAP or Active Directory, auto-provisioning and linking accounts
- Optional two-factor with recovery codes
- Personal API tokens for scripts and CI
Audit & notifications
- Every audited action records who did it
- Email over real SMTP, plus webhook, Slack and Discord channels
- Alerts on a failed schedule or a failed sync
- A "test channel" button that shares the real send path, so a pass means the real thing works
- Backups and their destinations have their own page
- Swarm sits alongside, for the clusters that still run it
Install & operate
- One container, one process — the UI is compiled into the binary
- No web folder has to travel with it
- The socket mount is only for managing the machine it runs on
- Every other host is added over SSH or TCP and needs no mount at all
- Listens on a single port
- A Compose file is included if you would rather start it that way
A look inside
Every page keeps its own address
Click any screenshot to read it full size.
Install
One command against your own machine. The data volume keeps accounts, hosts and stacks.
docker run -d --name mangodock -p 3100:3100 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v mangodock_data:/app/data \
ghcr.io/mangossh/mangodock:latestThe socket mount is only needed to manage the machine running the container itself. Every other host is added over SSH and needs nothing.
SQLite is the default and lives in that same volume — no second container, nothing to configure. Point MANGODOCK_DATABASE_URL at a postgres:// URL instead and MangoDock uses PostgreSQL; every migration is written dialect-neutral for exactly that. Keep the data volume either way: the database moves, but the key that decrypts every stored credential does not.
SQLite and PostgreSQL→Pricing
Priced per installation, not per container
One MangoDock manages as many Docker hosts as you point it at. The tiers differ in how many, and in what a team needs around them.
Free
Enough for a homelab or a single project.
$0up to 3 hostsDownload- Three Docker or Podman hosts, over a socket, SSH or TLS
- Containers, Compose stacks, images, volumes and networks
- Logs, terminal and the in-container file browser
- Vulnerability scanning with Trivy and Grype
- One account, with authentication still mandatory
Small teams
For a team running a handful of environments.
$399per yearBuy- Everything in Free, up to 15 hosts
- Unlimited accounts, with admin, operator and viewer roles
- SSO over OIDC, LDAP and Active Directory, and two-factor
- Backups to S3, Azure, B2 or your own destination, with restore
- GitOps: deploy from a repository, on a schedule or a webhook
- Scheduled jobs and notifications
Enterprise
For an estate, with the controls that implies.
$1,299per yearContact sales- Everything in Small teams, with no host or user limit
- The activity log, searchable and exportable
- Air-gapped installation, with offline vulnerability databases
- Registry mirrors and private registry browsing
- Priority support
A host is a Docker or Podman daemon MangoDock connects to, not a container. Containers are unlimited on every tier.
Download
No account and nothing phoning home. Every release publishes checksums beside it.
MangoDock is a container image. On a machine with internet access, pull it:
docker pull ghcr.io/mangossh/mangodock:latestAir-gapped install
For a host with no internet: the same image, its backup helper and agent, fresh Trivy and Grype databases and an installer, in one signed file. Verify it here, carry it across, run ./install.sh.
- Offline bundleLinux · x86-64 · about 720 MBDownload
Check it with cosign before carrying it across — download the signature next to it. The public key is read from this site.
cosign verify-blob --key https://mangossh.com/keys/mangodock-cosign.pub \
--bundle mangodock-offline-linux-x64.tar.gz.sigstore.json mangodock-offline-linux-x64.tar.gz



