Issue
Here's a Dockerfile that works:
# syntax=docker/dockerfile:1.0.0-experimental
FROM debian:buster-slim as base
# setup APT operation for noninteractive use
# This avoids a bunch of warnings like
# "debconf: unable to initialize frontend: Dialog"
ENV DEBIAN_FRONTEND=noninteractive
# install requirements
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
git \
openssh-client
# add a user
# RUN adduser --disabled-password app-user
# WORKDIR /home/app-user
# USER app-user
RUN mkdir --mode=0700 ~/.ssh
RUN printf "Host <bitbucket host>\n StrictHostKeyChecking no\n CheckHostIP no\n" >> ~/.ssh/config
RUN chmod 600 ~/.ssh/config
RUN --mount=type=ssh ssh-keyscan -t rsa <bitbucket host> >> ~/.ssh/known_hosts
RUN chmod 600 ~/.ssh/known_hosts
RUN --mount=type=ssh git clone --no-checkout 'ssh://git@<bitbucket host>/my/project.git'
The only thing I edited out is the actual Bitbucket host. Now, what doesn't work is activating the three commands following the "add a user" comment. If these three commands are activated, build fails with:
#20 [13/13] RUN --mount=type=ssh git clone --no-checkout 'ssh://git@bitbucke...
#20 digest: sha256:2ca1...
#20 name: "[13/13] RUN --mount=type=ssh git clone --no-checkout 'ssh://git@<bitbucket host>/my/project.git'"
#20 started: 2020-03-31 20:12:44.957895838 +0000 UTC
#20 0.648 Cloning into 'project'...
#20 1.170 git@<bitbucket host>: Permission denied (publickey).
#20 1.171 fatal: Could not read from remote repository.
#20 1.171
#20 1.171 Please make sure you have the correct access rights
#20 1.171 and the repository exists.
#20 completed: 2020-03-31 20:12:46.235264455 +0000 UTC
#20 duration: 1.277368617s
#20 error: "executor failed running [/bin/sh -c git clone --no-checkout 'ssh://git@<bitbucket host>/my/project.git']: exit code: 128"
rpc error: code = Unknown desc = executor failed running [/bin/sh -c git clone --no-checkout 'ssh://git@<bitbucket host>/my/project.git']: exit code: 128
Is this a bug in Docker? Am I missing an implication that this is not supposed to work somehow? Do I need to set up an additional level of forwarding between the root account and the new user account? How does git/ssh establish the communication to the agent in the first place? I checked /tmp
, /run
, mounts and the environment but couldn't find a pipe/socket.
The obvious workaround is to clone as root and then run chown -R
on it, but that that seems very unelegant. Also, I'd obviously like to understand what's going on.
Solution
The Buildkit --mount=type=ssh
directive remounts the host's ssh agent socket into the container with specific permissions. The default is owned by root (uid=0, gid=0) and unreadable by any other user (mode=0600).
You can add an option to make the socket be owned by some known non-root user:
# When you create the user specify its uid
RUN adduser --disabled-password --uid 999 app-user
USER app-user
# Also specify the uid as a mount option
RUN --mount=type=ssh,uid=999 ssh-keyscan ...
You could also make the socket accessible by other users (not a huge security concern, since it's only accessible for the lifetime of the single RUN
command and you control what it's running)
RUN --mount=type=ssh,mode=0666 ssh-keyscan ...
Answered By - David Maze Answer Checked By - Senaida (WPSolving Volunteer)