We have a tool which needs to clone several Git repositories for aggregating documentation data. We want to put that tool in a Docker container for easily running it locally and with Jenkins, and enabling reproducibility.
The Git repositories are hosted on a private server requiring authentication with SSH keys. Thus the Docker container must somehow gain access to the SSH keys of the user running the container.
We have a list of constraints:
Dockerfile
does not enable reproducibility whereas an already generated Docker image doroot
user-v
, -u
, …)Question: How can we achieve this, if it is possible?
Related:
root
)You can use something like:
echo "git-user:x:$(id -u):$(id -g):Git User:/tmp:/bin/bash" > /tmp/fake_passwd # See below why to use this
docker run \
-u $(id -u):$(id -g) \
-w /tmp \
-v $HOME/.ssh:/path/to/.ssh \
-v /tmp/fake_passwd:/etc/passwd \
--entrypoint sh \
-it \
alpine/git
# commands in the container:
$ export GIT_SSH_COMMAND='ssh -i /path/to/.ssh/id_rsa -o "StrictHostKeyChecking=no"'
$ git clone [path to git repo]
This will ensure the container runs with the same UID/GID as the host user, thus being able to read the keys without changing their permissions or using root rights. In details:
-u $(id -u):$(id -g)
set the container user to match the host user-w /tmp
ensure we work in a directory we can write in (we may also mount a volume on which we have read/write permissions or build the image with such directory)-v $HOME/.ssh:/path/to/.ssh
mounts the local user SSH key from the host--entrypoint sh
and -it
are specific to alpine/git
to have an interactive shell session, you may not need it with your image/etc/passwd
file?When you running a linux-based container (such as alpine
or debian
) with an unknown UID/GID (one which is not present in /etc/passwd
), git clone
command may result in error with a message such as:
Cloning into 'myrepo'...
No user exists for uid 1000
fatal: Could not read from remote repository.
By mounting this "fake" passwd file we ensure the OS will recognize the user running the container and allow our git clone command to work. Our password file will look like:
git-user:x:1000:1000:Git User:/tmp:/bin/bash
Which means roughly:
git-user
exists with UID 1000 and GID 1000 /tmp
(it's optional but this directory is writable and avoid some warning from git clone
)By setting /tmp
(or another directory which may be created during image build) we ensure we have a writable HOME directory for git-user
which will prevent a warning from git clone
saying it could not created a .ssh
directory
However this may have other side effects if you intend to run different tasks with your container.
GIT_SSH_COMMAND
?GIT_SSH_COMMAND='ssh -i /path/to/.ssh/id_rsa'
will ensure git clone
is using our key, but this can be done using ssh-agent as well - see https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
In the example I use -o "StrictHostKeyChecking=no"
but it may be insecure, another solution would be to mount a known host file in the container with the git repo server host key and using -o "UserKnownHostsFile=/path/to/KnownHostFile"
Would cloning the repositories on the host machine and mounting the directories in the docker image be ok ?
e.g. :
git clone github:repo1
git clone github:repo2
...
docker run -v repo1:/path/to/repo1 -v repo2:/path/to/repo2 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With