dockerenvironment-variablesdocker-secrets

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


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


Solution

  • 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".