Last week I had to perform what seemed like a very simple task: clone a private Github repository inside a docker container. Outside the container, I had SSH set up, so that I could clone the private repo using git clone ssh:git@github.com/myuser/myrepo.

As I dug deeper into documentation and forums, I've noticed that current documented solutions either relied on insecurely copying the hosts' ssh keys into the container or on hiding the copied ssh key through convoluted multi-stage builds.

However, as of version 18.09, Docker build now supports a way to use the host system's ssh access while building the image. This avoids the issue of copying private keys into the image and risking exposing them publicly. You can read more about it here as well.

This guide will help you set up a Dockerfile and a docker-compose.yml to work with the host system's SSH.

You can find the code on my github.

Setting up the host system's SSH

First, make sure that you have an SSH client installed and that you have set up a Github SSH key on your machine. Please follow this guide to connect to GitHub with SSH.

Once that's done, you can test your Github SSH connection by running the ssh -T git@github.com command on a terminal. If all works, you should see:

Hi jhonatan-lopes! You've successfully authenticated, but GitHub does not provide shell access.

Now, let's make sure that your SSH agent is running. We need to inspect the value of the environment variable SSH_AUTH_SOCK. On bash, run echo $SSH_AUTH_SOCK. If you see an output, the agent is running. Otherwise, you need to start the agent by running:

bash eval `ssh-agent -s` The next step is to add your credentials to the ssh-agent. Check which credentials you have added with:

bash ssh-add -l

If there aren't any credentials added, you need to add them to the agent. Let's add the id_ed25519 credential, which GitHub uses:

bash ssh-add ~/.ssh/id_ed25519

Note that these two steps (starting the agent and adding credentials) need to be done every time that you start a shell session, as the agent can get disconnected. If you wish to, there are some scripts that you can add to your .bashrc to auto-start the ssh-agent and add the credentials.

A Dockefile with SSH

Now let's create our Dockerfile:

```bash

Get a ubuntu image

FROM ubuntu

Update package databases

RUN apt-get update

Install ssh client

RUN apt install -y openssh-client

Download public key for github.com

RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

Test the connection

RUN ssh -T git@github.com ```

If built successfully, this image should show the same message that we got when testing our SSH connection before.

Let's try to build this image:

bash docker build .

gives:

bash git@github.com: Permission denied (publickey).

For it to work, we need to make the RUN command use the SSH agent that we set up:

```bash

Get a ubuntu image

FROM ubuntu

Update package databases

RUN apt-get update

Install ssh client

RUN apt install -y openssh-client

Download public key for github.com

RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

Test the connection

RUN --mount=type=ssh ssh -T git@github.com ```

Now we only need to pass along the ssh-agent to the docker build command:

bash docker build --ssh default .

You should now see:

Hi jhonatan-lopes! You've successfully authenticated, but GitHub does not provide shell access.

The build itself will fail, but we can ignore that. The ssh -T command is returning an error code even when the authentication is successful.

If that doesn't work, you might have to enable the build kit with an environment variable:

bash DOCKER_BUILDKIT=1 docker build --ssh default .

Now that we know that our connection is working, we can clone our repository:

```bash

Get a ubuntu image

FROM ubuntu

Update package databases

RUN apt-get update

Install ssh client

RUN apt install -y openssh-client git

Download public key for github.com

RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

Clone the private repo

RUN --mount=type=ssh git clone ssh:git@github.com:myuser/myprivaterepo.git ```

That's it! You now have your private repo cloned on your docker image using SSH.