linuxgitdockerssh

Git clone over SSH isn't working during docker image build for non-root user


My docker host is Debian 12.2. I can clone a private git repository over SSH in the host. I'm trying to do the same during a docker image build process. I'm forwarding my host's SSH agent during docker build. It's working when the root user is active during the build process, but doesn't work when the user is non-root. I need the process to work for non-root user for the purpose of the project I'm working on. Any help is appreciated.

The Dockerfile is as follows. This is a much simpler form of the whole Dockerfile used in my project to illustrate the problem.

FROM ubuntu:20.04 AS final-build
SHELL ["/bin/bash", "-c"]

# Required definitions to build the image
ARG DEBIAN_FRONTEND=noninteractive

# Install required software
RUN apt update && apt upgrade && apt install -y git

# Add & switch user
ARG USER
ARG UID
ARG GID
ARG PW=a
RUN useradd -m ${USER} --uid=${UID}
RUN echo "${USER}:${PW}" | chpasswd
# USER ${UID}:${GID}

ARG GIT_SERVER
ARG PROJECT

# Create the SSH directory and set permission
# Add repo to the list of known hosts for ssh
RUN mkdir -p ${HOME}/.ssh && \
    ssh-keyscan ${GIT_SERVER} >> ${HOME}/.ssh/known_hosts

ARG REPO=git@${GIT_SERVER}:<snip>
ARG BRANCH

WORKDIR ${HOME}/src

# Download project source code
RUN --mount=type=ssh git clone --branch ${BRANCH} --single-branch \
    ${REPO} ${PROJECT}

The docker image build process is as follows:

target="final-build"
eval $(ssh-agent)
ssh-add

options="-f Dockerfile \
    --build-arg GIT_SERVER=${GIT_SERVER} \
    --build-arg PROJECT=${PROJECT} \
    --build-arg BRANCH=${BRANCH} \
    --build-arg USER=${USER} --build-arg UID=$(id -u) \
    --build-arg GID=$(id -u) \
    --ssh default -t test --progress=auto"

# Build the docker image
docker buildx build --target=${target} ${options} .

The environment variables are loaded correctly as the repository is cloned properly with the above Dockerfile. However, if I uncomment this line:

USER ${UID}:${GID}

in the Dockerfile and try to build the image, I get the following error:

=> ERROR [final-build 8/8] RUN --mount=type=ssh git clone --branch main --single-branch     git@  0.3s
------                                                                                                  
 > [final-build 8/8] RUN --mount=type=ssh git clone --branch main --single-branch     git@<snip> <snip>:
0.174 Cloning into '<snip>'...
0.273 Warning: Permanently added the ECDSA host key for IP address '<snip>' to the list of known hosts.
0.326 git@<snip>: Permission denied (publickey,keyboard-interactive).
0.326 fatal: Could not read from remote repository.
0.326 
0.326 Please make sure you have the correct access rights
0.326 and the repository exists.
------
Dockerfile:35
--------------------
  34 |     # Download project source code
  35 | >>> RUN --mount=type=ssh git clone --branch ${BRANCH} --single-branch \
  36 | >>>     ${REPO} ${PROJECT}
  37 |     
--------------------
ERROR: failed to solve: process "/bin/bash -c git clone --branch ${BRANCH} --single-branch     ${REPO} ${PROJECT}" did not complete successfully: exit code: 128

Clearly, as soon as non-root user is switched to, the SSH agent which was forward become unavailable.

How to make it work for non-root user?

P.S.: I'd like to avoid copying SSH keys to the image due to the keys being available inside the image.


Solution

  • I've found the solution:

    RUN --mount=type=ssh,required=true,uid=${UID},gid=${GID} \
        git clone --branch ${BRANCH} --single-branch \
        ${REPO} ${PROJECT}
    

    --mount=type=ssh accepts uid and gid which can be used to represent a user.