Forwarding the Docker Socket over SSH

Lately, I’ve been working on some testing tools for Docker Swarm Mode. One of the things that is desirable is to be able to run docker commands locally, and have them execute on a remote cluster. In my case, it lets me develop tests locally without having to cross-compile and then copy files.

A little-known trick that OpenSSH can do since 6.7 is forward Unix domain sockets over SSH using the same syntax used for port forwarding. The command I run looks a bit like this

ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock user@someremote

This will open up a socket called docker.sock in the working directory that is forwarded over SSH to /var/run/docker.sock on the remote host. the -nNT option tells SSH to run -no command, redirect -NULL to stdin, and do not allocate a -TTY. This stops you from running commands over the tunnel you just created. If you want, you can drop those options and ALSO have shell access to the remote; the socket forwarding will work the same either way.

Now, without closing the SSH instance you just opened, you can in a different terminal do

export DOCKER_HOST=$(pwd)/docker.sock

This sets Docker for the duration of this shell instance to use that local socket as the Docker socket. Now, any docker commands you run get passed through the local socket, forwarded to the remote socket, and the responses get sent right back to you. You can use docker exactly the same as you do otherwise, including attaching containers with TTYs.

Note, you must delete the local socket file that SSH creates after you close SSH; it does not go away automatically. If that socket file already exists when you run the ssh command to create it, the command will fail.

Neat trick!