Search code examples
node.jsdockerdocker-secrets

How to pass secret via dockerfile mount?


I am unable to run dockerbuild to mount a secret to pass to the container. This is an example public repo to show the problem in github: https://github.com/inspiraller/docker-node-get-secrets

Dockerfile

FROM node:20
WORKDIR /usr/src/app
COPY node-files .
RUN npm ci && npm run build
ENV NODE_ENV=production
RUN --mount=type=secret,id=THEPASSWORD1   #,target=./run/secrets/THEPASSWORD1
CMD ["node", "dist/get-secrets.js"]

I tried to follow the guidelines on the main docker website: https://docs.docker.com/build/building/secrets/

The intention is to pass my local file ./.secrets/THEPASSWORD1 (which contains the value) to /run/secrets/THEPASSWORD1

  1. docker build -t distroless-node-dumbinit:1 --secret id=THEPASSWORD1,src=./.secrets/THEPASSWORD1 --secret id=THEPASSWORD2,src=./.secrets/THEPASSWORD2 --no-cache .

When I run this container: docker run --name distroless-node-dumbinit distroless-node-dumbinit:1 It doesn't work

Though when I use docker-compose.yml, using a different approach it does work.

I am expecting the console.log the value of THEPASSWORD1 in my get-secrets.js node file. It is expecting to get the secret from /run/secrets/THEPASSWORD1


Solution

  • For anyone else with this problem. Here is a working example with passing secrets into an image single line. Note. You woudn't don't this normally, but this is just to show it working.

    Dockerfile

    FROM debian:stable-slim
    COPY private-install-script.sh .
    
    # For the next 2 commands comment one or the other out to prove that ACCESS_TOKEN will only be available to the first comnand
    
    # 1. Doing RUN here of private-install-script.sh is going to output that token back to a file /tmp/dontdothis
    RUN --mount=type=secret,id=ACCESS_TOKEN ENV_ACCESS_TOKEN=$(cat /run/secrets/ACCESS_TOKEN) ./private-install-script.sh
    
    # 2. Doing RUN here will NOT pass ACCESS_TOKEN. This is just an example to prove it won't pass it in. 
    # RUN ./private-install-script.sh
    # -----------------
    # Now display the contents of /tmp/dontdothis
    CMD ["cat", "/tmp/dontdothis"]
    

    private-install-script.sh

    #!/bin/sh
    
    # ON BUILD
    echo "ENV_ACCESS_TOKEN=${ENV_ACCESS_TOKEN}. cat run/secrets/ACCESS_TOKEN=$(cat /run/secrets/ACCESS_TOKEN)" > /tmp/dontdothis
    

    Create secret via terminal export ACCESS_TOKEN=mysupersecret123

    Create the build (will use the above created secret)

    docker build --secret "id=ACCESS_TOKEN" -t build-secret:1 .

    Run the build

    docker run --name build-secret build-secret:1

    mysupersecret123

    To prove the secret is not acessible via the build

    1. docker image history build-secret:1 --no-trunc