Hosts

August 4, 2026 · View on GitHub

← Manual index

Hosts

Manage the Docker daemons Docker Commander talks to. The local host exists out of the box; add remote ones and switch between them with the sidebar switcher. Every view, stream and the alert engine bind to the selected host.

Adding a host

  • TCP — address tcp://host:2376, with optional CA / client cert / key (PEM) for TLS.
  • SSH — address user@host[:port]. Authentication uses the server's own SSH agent / ~/.ssh keys (no key material is stored here). The Docker API is tunnelled to the remote daemon's socket over SSH.

You can set a per-host alert email (overrides the global SMTP recipient for alerts from that host) at creation or inline on the host card.

The remote server only needs Docker installed and reachable — it does not need Docker Commander. One Docker Commander instance talks to many remote Docker daemons; it never talks to another Docker Commander.

Connecting a remote host — worked example

Nothing is exposed to the network and no secrets are stored here — Docker Commander tunnels the Docker API over SSH using the OS user's own SSH keys (the user that runs the dockercmd process).

On the Docker Commander server, as the user that runs dockercmd:

# 1. Have an SSH key (skip if you already do) and install it on the remote host:
ssh-keygen -t ed25519
ssh-copy-id deploy@10.0.0.42

# 2. Sanity check — this must succeed WITHOUT a password prompt:
ssh deploy@10.0.0.42 docker info

On the remote host, the SSH user must be allowed to reach the Docker socket:

sudo usermod -aG docker deploy    # then reconnect so the group takes effect

Then in the UI: Hosts → Add host → SSH, address deploy@10.0.0.42 (or deploy@host:2222 for a custom port) → TestTrust this host after verifying the SSH host-key fingerprint (see below).

Key auth uses the server's SSH agent or ~/.ssh keys. For a passphrase- protected key, make sure an agent is available to the dockercmd process (e.g. systemctl service with SSH_AUTH_SOCK, or a passphrase-less key dedicated to this).

The remote sshd must allow forwarding. The Docker API is tunnelled to the remote socket over an SSH channel, which sshd gates on AllowTcpForwarding — so a hardened config with AllowTcpForwarding no fails with ssh: rejected: connect failed. Most distributions default to yes; Alpine ships no. Note that sshd honours the first occurrence of a keyword, so append-only edits to sshd_config can be silently ignored — check the effective value with sshd -T | grep -i allowtcpforwarding.

This also produces a confusing half-working host: docker compose reaches the remote over its own dial-stdio channel, which needs no forwarding, so a Projects deploy can succeed while monitoring and every other operation fails. If a host tests fine for deploys but shows nothing on the dashboard, check this first.

If your agent holds several keys, sshd may reject them all and hit its MaxAuthTries (default 6) before reaching the right one. Either prune the agent or dedicate a key to this host.

Option 2 · TCP + TLS

Prefer SSH (Option 1) — it exposes no extra port. Reach for TCP only when SSH genuinely isn't possible, and treat it carefully:

⚠️ The Docker daemon socket is root-equivalent. Anyone who can reach it can mount the host filesystem and run privileged containers, i.e. become root on that machine. So:

  • Never expose plaintext 2375 — that is an open root shell to the world.
  • 2376 must use mutual TLS (--tlsverify): a leaked client cert is a root credential, so guard it like one.
  • Even with TLS, don't put 2376 on the open internet. Keep it on a private network / VPN (e.g. WireGuard) or restrict it with a firewall allowlist to the Docker Commander server's IP, and bind the daemon to that specific interface — not 0.0.0.0.
  1. On the remote host, enable a TLS-protected TCP listener on :2376 and generate a CA + server + client certificates — follow Docker's official guide: https://docs.docker.com/engine/security/protect-access/.
  2. In the UI: Hosts → Add host → TCP (+TLS), address tcp://10.0.0.42:2376, and paste the CA cert, client cert and client key (PEM) into the three fields.

Quick sanity check from the Docker Commander server:

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
  -H tcp://10.0.0.42:2376 info

Switching the active host

With more than one host configured, a Viewing host switcher appears at the top of the sidebar. Pick a host and the whole app — dashboard, containers, images, logs, stats, exec — rebinds to it; the rest stays focused on that one host (so nothing is "mixed" across servers). The currently active host is also shown as a badge in every page header. The selection is remembered in your browser. (The switcher is hidden when only the local host exists.)

Host detail

The ℹ️ button on a host card opens its hardware / OS / engine summary: CPUs, memory, architecture, OS and kernel, Docker version, storage & logging drivers, cgroup, and the current container/image counts.

Docker Desktop: the engine runs inside a Linux VM, so these values describe that VM, not the Windows/macOS host — the Docker API can't see the underlying OS. The kernel is the best hint (e.g. …-WSL2 ⇒ Windows/WSL2).

Not seeing a host you know exists? Besides being disabled (below), a host can simply be outside your host scope — the list, the switcher and every per-host view only show hosts your grants reach. See Users & roles → Host scope.

Reachability monitoring

Beyond the on-demand Test button, the background monitor pings every enabled host every 30 seconds and tracks whether its Docker daemon is reachable. When a host can't be reached, a 🔴 unreachable badge appears on its card and next to its name in the host switcher; it clears automatically once the daemon answers again.

A change of state also raises an alert: a host going offline fires a critical event, and its recovery fires an info event (noting how long it was down). Recovery is automatic: a failed probe drops the cached connection, so the next sweep dials afresh rather than retrying a socket that died with the peer. These land in the Alerts feed and, if SMTP is set up, are emailed — to the host's own Alert email if set, otherwise the global recipient. This watch is automatic and needs no alert rule. To avoid noise on startup, the very first probe never alerts — a host that is already down when the server boots stays quiet until it actually changes state. Disabled hosts are not probed (and never show the badge).

Disabling a host

The button on a host card toggles it disabled. A disabled host is ignored by the monitor — no Docker-events stream, no stats sampling — and is dropped from the host switcher (there's nothing to view). This is the clean way to handle a host that's temporarily offline (a laptop that's been put away, a server being maintained): instead of the monitor retrying and logging errors, just disable it. Re-enable it with the same button when it's back. Disabling a host also drops its cached connection so nothing keeps reaching for it.

SSH host-key verification

On first contact with an SSH host the daemon's host key is checked against ~/.ssh/known_hosts, then against a key you've trusted here:

  • UnknownTest shows the SHA-256 fingerprint and a Trust this host button (trust-on-first-use). Verify the fingerprint out-of-band before trusting.
  • Changed → refused as a possible man-in-the-middle; re-trust only if you changed the host deliberately.

Test

Test probes a host (bounded so an unreachable host fails fast) and reports the Docker version + running count, or the connection / host-key problem.

Tips

  • Remote alerting/metrics “just work” — the engine watches every configured host, and alerts carry which host they came from.
  • Don't expose remote/SSH hosts until host-key verification is satisfied.