Git clone private repo during Docker build Link to heading

You may want to build a docker image, which directly clones from a private repo, such as from Github, using a ssh key. Believe it or not, this is not as straightforward as it sounds.

First, we need to feed in the public/private keys in order to clone a private repo. Obviously, we don’t want to hard-code the private key into the Dockerfile or the container image for security reasons. Docker provides an option to set a build-time variable with --build-arg. To use it, one declares the argument in the Dockerfile with ARG command. For example, create Dockerfile as below

FROM ubuntu:22.04
ARG key
RUN echo "$key" > /root/key

and build the image by supplying the argument. We can see the command echo "hello" in the log.

$ docker build -t test --build-arg key=hello .
[+] Building 0.6s (6/6) FINISHED                                                                                                                           
 => [internal] load build definition from Dockerfile                                                                                                   0.0s
 => => transferring dockerfile: 73B                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/ubuntu:22.04                                                                                        0.6s
 => [1/2] FROM docker.io/library/ubuntu:22.04@sha256:2a357c4bd54822267339e601ae86ee3966723bdbcae640a70ace622cc9470c83                                  0.0s
 => CACHED [2/2] RUN echo "hello" > /root/key                                                                                                          0.0s
 => exporting to image                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                0.0s
 => => writing image sha256:c05e48ca6aca34d69523e1ab178afa077f8f3e7900008e76b3b2538dca24517a                                                           0.0s
 => => naming to docker.io/library/test   

Next, we need to let the build system know that github.com can be trusted. For that, we can add the following command in the Dockerfile before git clone

RUN ssh-keyscan github.com >> /root/.ssh/known_hosts

With these two tricks, we can clone a private repo from Github during the docker build process. For example, create Dockerfile:

FROM ubuntu:22.04
RUN mkdir ~/.ssh
ARG ssh_prv_key
ARG ssh_pub_key
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub && \
    ssh-keyscan github.com >> /root/.ssh/known_hosts && \
    git clone [email protected]:PRIVATE/REPO.git && \
    rm /root/.ssh/id_rsa*

and run the following command to build the image:

$ docker build -t example --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" .