Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Docker Tip #56: Volume Mounting SSH Keys into a Docker Container

blog/cards/docker-tips-and-tricks.jpg

On paper this sounds easy. Just mount in your SSH directory and you're done, but it's not that simple with Windows based Docker hosts.

It starts off easy. Just run: docker run --rm -it -v ~/.ssh:/root/.ssh:ro alpine.

If you’re running Linux or MacOS, that’s all you need to do. I like adding in the extra :ro bit to the volume mount to make it read-only. This just removes the possibility of you overriding your SSH keys in the container by accident.

But What about Windows (specifically WSL)?

There’s 2 problems.

PROBLEM 1. Permissions are busted:

Unfortunately Windows doesn’t respect Linux file permissions. Your SSH folder and files will all be set to 777 and SSH won’t work with those permissions.

As of Windows 10 Spring 2018 edition, you can mount in your drives into WSL using metadata which supports Linux file permissions, and that’s fantastic, but Docker for Windows mounts that drive in through CIFS and that will strip out the metadata.

So you’re stuck with 777 permissions when mounting in your SSH keys through Windows.

PROBLEM 2. You can’t Docker volume mount files from directly inside of WSL:

In addition to the above problem, you can’t mount in files that exist directly in your WSL drive. They will come up empty, so mounting ~/.ssh doesn’t work.

But you can get around this one easy enough. You just need to copy your SSH keys to somewhere that gets mounted into WSL, rather than living directly in WSL’s file system.

I personally back up my files to an external HD, so I was doing that anyways.

Fixing the problem with a Docker ENTRYPOINT script:

First up, make a docker-entrypoint.sh script in the same directory as your Dockerfile. Then add this content to that file:

#!/bin/sh
set -e

cp -R /tmp/.ssh /root/.ssh
chmod 700 /root/.ssh
chmod 644 /root/.ssh/id_rsa.pub
chmod 600 /root/.ssh/id_rsa

exec "$@"

Then, in your Dockerfile, add this right above your CMD instruction:

COPY docker-entrypoint.sh /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh
ENTRYPOINT ["/bin/docker-entrypoint.sh"]

Now, run your container like this:
docker run --rm -it -v /e/backup/home/nick/.ssh:/tmp/.ssh:ro your_image.

(Replace /e/backup/home/nick/.ssh with where your SSH keys are located)

The idea here is, you’re mounting in your SSH keys from outside of WSL’s main file system into the container at a temporary location (and it’s still read-only).

Then when the container starts, the ENTRYPOINT kicks in and copies everything to the correct location with the correct permissions.

Problem solved, you can now use your SSH keys!

If you’re a Docker image author and you require users to volume mount in their SSH keys, please think about people running Windows by including the above ENTRYPOINT script. They will really appreciate it.

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.


Comments