Adding secret to docker build, from environment variable rather than a file
Asked Answered
J

3

11

Assuming the latest Docker with BuildKit enabled, the documentation suggests that the --secret option has file and env types. I want to use the env type like this:

MYSECRET=thepassword
docker build --secret id=mysecret,env=MYSECRET -t myimage .

In the dockerfile, the secret would be accessed like:

RUN --mount=type=secret,id=mysecret \
    PASSWORD=$(cat /run/secrets/mysecret) && \
    <run command taking password arg> ${PASSWORD}

This approach fails with cat: /run/secrets/mysecret: No such file or directory

A similar issue was asked here but the extra steps writing the secrets into the .condarc file inside the docker image aren't important to me. According to that post, the basic operation of getting a local environment var passed into the docker build for the scope of a single RUN statement should "work", but it doesn't for me.

The build command above runs fine until it tries to access the file path that is supposed to be mapped to the secret. Trying temporarily to pass MYSECRET into the build as a --build-arg shows that the env var can be resolved.

The documentation suggests that --secret will even default to the "env" mode by supplying only the id:

MYSECRET=thepassword
docker build --secret id=MYSECRET -t myimage .
RUN --mount=type=secret,id=MYSECRET \
    PASSWORD=$(cat /run/secrets/MYSECRET) && \
    <run command taking password arg> ${PASSWORD}

When I try this, it actually throws an error sooner, before starting the build:

could not parse secrets: [id=MYSECRET]: failed to stat MYSECRET: stat MYSECRET: no such file or directory

leaving me to believe that it's still trying to use file mode, not env mode at all.

If I choose to store my secret in a file and load it using the file mode, that works. Because of some details about a build pipeline I would rather use the env mode if I can.

Has anyone run into this problem?

I'm building Linux docker images on a Mac M1 running Docker Desktop 4.17.0 with Docker engine 20.10.23

Jigsaw answered 8/3, 2023 at 2:18 Comment(1)
did you find a solution to the cat: /run/secrets/mysecret: No such file or directory?Subaqueous
M
6

Here's a post that helped me solve this.

Essentially, when running build you pass --secret argument.

export MY_SECRET=foo
docker build --secret id=my_secret_id,env=MY_SECRET -t my_image .

then from Dockerfile you can access it by mounting it like so:

RUN --mount=type=secret,id=my_secret_id \
 export MY_SECRET=$(cat /run/secrets/my_secret_id) && \
 echo $MY_SECRET # would output "foo".
Modernize answered 18/12, 2023 at 14:54 Comment(2)
I had to add && between the export and echo for this to work.Deferential
Not work for me with error: ERROR: failed to solve: failed to load cache key: invalid mountinput dest:"/run/secrets/my_secret_id" mountType:SECRET secretOpt:<ID:"my_secret_id" mode:256 optional:true >Hail
J
1

It works for me when I export the variable.

Instead of

MYSECRET=thepassword

try to write

export MYSECRET=thepassword
Jude answered 12/3 at 16:50 Comment(1)
This should be the accepted solution. The OP is using a shell variable, where Docker only accepts environment variables, which are declared using export. I ran into this issue today, and this was the solution.Ganef
K
0

Does this work?

Dockerfile:

RUN --mount=type=secret,id=MYSECRET PASSWORD=$(cat /run/secrets/MYSECRET) && \ 
<run command taking password arg> ${PASSWORD}

Terminal (here I am skipping ,env=, which is optional):

docker build --secret id=MYSECRET -t myimage .
Koweit answered 16/3, 2023 at 17:23 Comment(2)
No, it doesn't seem to work.Kellyekellyn
not working for me as wellFreeland

© 2022 - 2024 — McMap. All rights reserved.