Skip to content

fix: lazydocker can't use DOCKER_HOST=ssh:// on Tailscale SSH - #831

Open
nicobonada wants to merge 1 commit into
jesseduffield:masterfrom
nicobonada:feat/ssh-dial-stdio
Open

fix: lazydocker can't use DOCKER_HOST=ssh:// on Tailscale SSH#831
nicobonada wants to merge 1 commit into
jesseduffield:masterfrom
nicobonada:feat/ssh-dial-stdio

Conversation

@nicobonada

Copy link
Copy Markdown

Summary

When connecting to a remote Docker daemon via ssh:// (DOCKER_HOST or an SSH Docker context), lazydocker currently opens an SSH streamlocal tunnel to /var/run/docker.sock and rewrites the client to a local unix socket (pkg/commands/ssh).

The Docker CLI instead uses docker system dial-stdio over SSH (github.com/docker/cli/cli/connhelper). That path works in places the streamlocal tunnel does not—most notably Tailscale SSH, which refuses unix-socket forwards to /var/run/docker.sock (allowlist is home / /tmp / /run/user/<uid> only). Result today: docker ps works, lazydocker times out on the tunnel.

This PR switches ssh:// client setup to the official connhelper (same approach as the CLI) and removes the custom tunnel package.

Changes

  • newDockerClient: for ssh:// hosts, use connhelper.GetConnectionHelper + client.WithDialContext (dial-stdio); leave unix/tcp hosts unchanged
  • Drop pkg/commands/ssh (streamlocal tunnel + tests that only covered that path)
  • Still export DOCKER_HOST for the resolved host when unset, so subprocess docker / compose invocations see the same target (including ssh://)
  • Close the Docker client via Closers (replaces the old tunnel closer)

No new dependencies: docker/cli (and connhelper) were already vendored.

Why not keep the tunnel

Streamlocal (-L …:/var/run/docker.sock) dial-stdio
Who opens the socket SSH server forward path Remote docker as the user
Docker CLI Not used for ssh:// Yes
Tailscale SSH Blocked for /var/run/docker.sock Works

Aligning with the CLI is the durable fix; special-casing Tailscale would not help other restricted SSH setups.

Testing

  • GOFLAGS=-mod=vendor go test ./pkg/commands/ (and full package tests under the same flags as CI)
  • Manual: DOCKER_HOST=ssh://user@host lazydocker against a host served by Tailscale SSH — containers list matches docker ps
  • Manual: same binary against OpenSSH (non–Tailscale SSH) still works
  • Non-SSH local/unix DOCKER_HOST unchanged

Related issues

(Also relevant background: #213, #228 — earlier SSH / DOCKER_HOST friction.)

Notes for reviewers

  • Branch base: master
  • Behavioural change is limited to connection setup for ssh://; UI and API usage are unchanged
  • Happy to adjust commit message / split further if preferred

Replace streamlocal SSH forwarding of /var/run/docker.sock with the
official docker/cli connhelper path (ssh … docker system dial-stdio).

Matches the Docker CLI and works with restricted SSH servers such as
Tailscale SSH that refuse unix socket forwards outside user directories.
@nicobonada nicobonada changed the title fix: connect to ssh:// Docker hosts via dial-stdio (connhelper) fix: lazydocker can't use DOCKER_HOST=ssh:// on Tailscale SSH Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker context ssh tunnel fails! using DOCKER_HOST: ssh tunneled socket never became available

1 participant