I've worked on a few projects recently where we've wanted a Docker container to be able to SSH into other machines on the network. The approach we settled on was to let the Docker container share the SSH agent of the host machine.

Why would you want to do this?

In this situation these projects were Rails or Node.js applications that use Docker for development and the CI process, but in production the application is run traditionally – directly on top of the operating system.

These applications used either Capistrano or Shipit to automate the deployment of the applications, and we didn't want to re-write the deploy process just because we'd decided to adopt Docker for development and CI.

The challenge comes when Capistrano or Shipit runs from within the Docker container and needs to perform a task using SSH/SCP – our Docker container doesn't contain any SSH keys (as you'd probably expect).

As we already have a secure way for populating and managing SSH keys on our CI nodes before Docker was introduced as a technology sharing the SSH agent of the host with the container provided a very low friction route to deploying our application from within the container that is used to run the tests as part of our CI process. This seemed like a sensible approach as conceptually it is very similar to SSH agent forwarding between hosts.

Sharing the SSH Agent

To shared the SSH agent between your host machine and your docker container all you need to do is set an environment variable and a volume mount in your docker setup.

Here is an example of what this will look like with a fictitious docker-compose.yml:

version: '3'

    container_name: yourcontainer
      - SSH_AUTH_SOCK=/ssh-agent
    image: yourapp
      - ${SSH_AUTH_SOCK}:/ssh-agent

In the container, we're setting the environment variable SSH_AUTH_SOCK to the path /ssh-agent. We're then mounting the host's SSH agent socket path onto /ssh-agent within the container.

With this in place, you will now be able to run any SSH command from within your docker container as if you were running the command from the host machine.