How can I read --secret args passed to docker build as environment variables to write to a file?

Viewed 846

I'm trying to use the secrets Buildkit feature. I want to inject the secret via an environment variable- not a file.

I'm running this build command

DOCKER_BUILDKIT=1 \
MYSECRET=theverysecretpassword \
docker build \
--secret id=MYSECRET \
-t myimage .

This runs without issue. If I change the name of the env var I'm exporting it fails saying it cannot find it- that gives me confidence it's grabbing the env var correctly.

But I cannot figure out how to access the secret in the Dockerfile.

I tried writing it to a file like this:

# syntax=docker/dockerfile:1.4
FROM condaforge/mambaforge

RUN echo $MYSECRET > /tmp/secret

But when I run and exec into the container and run cat /tmp/secret the file is empty:

docker run -it --entrypoint /bin/bash myimage

Am I doing something wrong?

Edit

I have found a solution, but it's very messy. It seems secrets can only be accessed in RUN targets mounted as files- is this correct?

This works, but I'm not sure if my history will be clean of secrets. Is this secure?

FROM condaforge/mambaforge

SHELL ["/bin/bash", "-c"]

RUN --mount=type=secret,id=USERNAME \
    --mount=type=secret,id=PASSWORD \
    export USERNAME=$(cat /run/secrets/USERNAME) && \
    export PASSWORD=$(cat /run/secrets/PASSWORD) && \
    echo "channels:" > /root/.condarc && \
    echo "  - https://$USERNAME:$PASSWORD@zzzz.jfrog.io/zzzz/api/conda/aaaaa" >> /root/.condarc && \
    echo "  - https://$USERNAME:$PASSWORD@zzzz.jfrog.io/zzzz/api/conda/bbbbb" >> /root/.condarc

# Run commands that use /root/.condarc

# After done delete /root/.condarc. Will this prevent secrets from getting into my docker history?

Also, I was previously using the new heredoc syntax and COPY to write to a file, this is really nice:

# syntax=docker/dockerfile:1.4
FROM condaforge/mambaforge

COPY <<EOF /root/.condarc
channels:
  - https://$USERNAME:$PASSWORD@zzzz.jfrog.io/zzzz/api/conda/aaaaa
  - https://$USERNAME:$PASSWORD@zzzz.jfrog.io/zzzz/api/conda/bbbbb
EOF

Is it possible to use the --secret arg with COPY? Can the COPY directive read from --secret args somehow? It would be much more readable.

1 Answers

I suggest writig the content of .condarc locally to a file and mount that right away to the right place.

docker build --secret id=condarc,src=.condarc .

And in the Dockerfile mount it like this:

RUN --mount=type=secret,id=condarc,dst=/root/.condarc ...

Make sure you have the local .condarc in your .dockerignore in case you copy with glob pattern or dot.


Also note that if you write a mounted secret to another file, like you did with echo, and use this new file in a later instruction, it will be added to a layer and in the history. Deleting it in a later instruction is not safe, if you need to do this, with echo or similar, make sure you delete it in the very same RUN instruction, the secret was mounted.

Related