iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🐳

[Docker] The uid option for RUN --mount=type=ssh

に公開

Introduction

This article assumes some prior knowledge of Docker BuildKit. If you would like to learn more about BuildKit, please refer to the official documentation or other articles.

https://docs.docker.com/build/buildkit/

To be honest, reading the link above might not be enough to understand everything. For specific features like --mount, you will likely need to look them up individually, such as checking the RUN section in the Dockerfile reference.

https://docs.docker.com/engine/reference/builder/

About --mount

Suppose you want to build a Docker image that depends on the contents of a private Git repository.
In the past, there were primarily two ways to do this: either git clone on the host (which holds the credentials) and use the COPY command, or COPY the private key to the image and git clone during the build process. With the latter method, you had to be especially careful to use multi-stage builds to ensure the private key wasn't inadvertently left in the image [1].

Since Docker 18.09, BuildKit has become available, allowing us to benefit from several useful features like parallelization. One of these features is --mount, which can be specified in a Dockerfile to mount a filesystem and reference it during the build.

https://docs.docker.com/engine/reference/builder/#run---mount

You can specify the type of mount, such as bind, cache, secret, or ssh. When you want to perform a git clone, ssh is the appropriate choice.

For example, if you create a Dockerfile with the following content and try to build it normally, you will naturally get a "Permission denied" error.

FROM ubuntu

RUN apt-get update
RUN apt-get install -y ssh

RUN mkdir -m 700 ~/.ssh
RUN ssh-keyscan github.com > ~/.ssh/known_hosts

RUN ssh -T git@github.com
$ docker build .
:
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
git@github.com: Permission denied (publickey)
:

However, by prefixing the command with --mount=type=ssh, enabling BuildKit [2] with DOCKER_BUILDKIT=1, and passing --ssh default, SSH authentication will succeed as shown below.
(Though the build still fails because the exit code is 1.)

FROM ubuntu

RUN apt-get update
RUN apt-get install -y ssh

RUN --mount=type=ssh ssh -o StrictHostKeyChecking=no -T git@github.com
$ DOCKER_BUILDKIT=1 docker build --ssh default --progress plain build .
:
#9 1.720 Hi eduidl! You've successfully authenticated, but GitHub does not provide shell access.
:

When trying to run as a non-root user

However, if you create a dev user and try to do the same thing as that user, it will fail.

FROM ubuntu

RUN apt-get update
RUN apt-get install -y ssh

RUN useradd -m -u 1000 dev
USER dev

RUN mkdir -m 700 ~/.ssh
RUN ssh-keyscan github.com > ~/.ssh/known_hosts

RUN --mount=type=ssh ssh -T git@github.com
$ DOCKER_BUILDKIT=1 docker build --ssh default --progress plain build .
:
#10 1.214 git@github.com: Permission denied (publickey).
:

This is because, by default, the mount is only visible to the user with uid=0. It will work again if you explicitly specify uid=1000 (corresponding to useradd -u 1000) in the Dockerfile.

FROM ubuntu

RUN apt-get update
RUN apt-get install -y ssh

RUN useradd -m -u 1000 dev
USER dev

RUN mkdir -m 700 ~/.ssh
RUN ssh-keyscan github.com > ~/.ssh/known_hosts

RUN --mount=type=ssh,uid=1000 ssh -T git@github.com
$ DOCKER_BUILDKIT=1 docker build --ssh default --progress plain build .
:
#10 1.942 Hi eduidl! You've successfully authenticated, but GitHub does not provide shell access.
:

Other available options can be found here:

https://docs.docker.com/engine/reference/builder/#run---mounttypessh

References

I solved the issue by referring to this when I had no idea what the cause was:

https://stackoverflow.com/questions/74793665/can-i-use-docker-buildkit-to-provide-an-ssh-key-to-a-non-root-user

脚注
  1. Nonetheless, it feels like this happens naturally when trying to minimize image size. ↩︎

  2. It is also possible to always enable BuildKit in /etc/docker/daemon.json (https://docs.docker.com/build/buildkit/#getting-started) ↩︎

GitHubで編集を提案

Discussion