Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clone a Git repository from a Docker container

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:

  1. we do not want to embed SSH keys in the Docker image
  2. we do not want users to build the Docker image. We consider a Dockerfile does not enable reproducibility whereas an already generated Docker image do
  3. we do not want the container to run as the root user
  4. we want to use the SSH keys of the host user running the container
  5. parameters can be provided to the command starting the container (-v, -u, …)

Question: How can we achieve this, if it is possible?

Related:

  • Using SSH keys inside docker container (the SSH keys are passed at build time − we want run time)
  • Clone private git repo with dockerfile (same problem)
  • Inject host's SSH keys into Docker Machine with Docker Compose (running as root)
like image 997
Jim Avatar asked Jun 07 '19 09:06

Jim


2 Answers

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"

like image 72
Pierre B. Avatar answered Oct 16 '22 05:10

Pierre B.


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 ...
like image 26
LeGEC Avatar answered Oct 16 '22 05:10

LeGEC