How to clone a Git repository from a Docker container

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 ...

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

Why mount a fake /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
  • it's HOME directory is /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.

Why use 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"