Using Socket Forwarding for Docker Engine and Compose

When working with Docker (engine) on remote machines and Docker Compose on local machines it is very useful to setup Unix Domain Socket Forwarding because you no longer need to transfer Compose Files to the remote machine. Rather now you can execute the client program docker-compose in your local shell and by setting the environment variable DOCKER_HOST to your forwarding socket all subsequent commands are forwarded to the remote Docker Engine.

Update: Since Docker 18.09 it is possible to directly set an ssh connection string as DOCKER_HOST variable value ... see this blog post as an alternative to the way shown here.

Requirements

OpenSSH 6.7

Possible Issues

Docker for Mac: Support for sharing unix sockets
https://github.com/docker/for-mac/issues/483

Setting up the Socket Forwarding

Depending on your environment (here it is Docker on a Ubuntu based VM in Virtualbox) this one is optional but you should add the<user> to the docker group (so you don't need to pass sudo through the socket forwarding):

# On e.g. Ubuntu you can add the <user>, check the result and exit
ssh -i /path/to/<key_file> -t <user>@<host> "sudo usermod -aG docker <user>;groups <user>;exit;"

Now the actual socket forwarding local_socket:remote_socket ... so you forward a local socket called <socket> (e.g. dev1_docker.sock) to the remote docker.sock. Details on the command can be found in the manpage.

ssh -i /path/to/<key_file> -t -f -L /path/to/local/<socket>:/var/run/docker.sock -N <user>@<host>

As mentioned, it requires OpenSSH 6.7.

The nice thing is that this socket forwarding is available not only in your current shell, but also on all shells you open. However, in every new shell where you want to access this socket you need to set/export the environment variable DOCKER_HOST:

export DOCKER_HOST=unix:///path/to/local/<socket>

Now test it by e.g.:

docker ps -a

Removing the Socket Forwarding

You can see the current processes related to ssh by e.g.:

ps aux | grep ssh

To stop the process related to your socket forwarding you can e.g. grep for its path (and ignore the grep itself: grep -v grep), filter its id and then kill it:

kill $(ps aux | grep /path/to/local/<socket>:/var/run/docker.sock:/var/run/docker.sock | grep -v grep | awk '{print $2}')

After removing the the socket you need to clear, "remove" the environment variable DOCKER_HOST:

unset DOCKER_HOST

In contrast to the automatic file creation on setup you now need to manually remove the local socket file:

unlink /path/to/local/<socket>

And again depending on your environment remove the <user> from group docker, check the result and exit:

ssh -i /path/to/<key_file> -t <user>@<host> "sudo deluser <user> docker; groups <user>;exit;

Have fun working with that ... especially when making a little script out of it, it helps to easily connect to your VM and be setup for working with docker on the VM and docker-compose on your laptop.

Further Information:

OpenSSH:
https://man.openbsd.org/ssh
https://www.openssh.com/txt/release-6.7

Issue with Docker For Mac:
https://github.com/docker/for-mac/issues/483

This post was inspired by:
https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160