Building docker images in CIs using secrets
I spent more time than I would like to admit trying to solve a problem I thought would be standard in the Docker world: passing a secret to Docker build in a CI environment (GitHub Actions, in my case).
This post is not about mounting a file with environment secrets, as there are already good posts about it (such as this one). Instead, I needed to pass an environment variable as a secret for building my Docker container using GitHub Actions.
The solution turned out to be simple, but with one limitation: you can only use one secret per RUN statement in the Dockerfile.
To build the Docker image, you can pass the secret from an environment variable like this:
docker build --secret id=env,env=MY_SECRET -t my_image .
This will take the environment variable MY_SECRET and allow the Dockerfile to mount it as a file.
For example, if we need to pass an Npm token when installing the packages of a NodeJS application, we would do the following:
RUN --mount=type=secret,id=env export MY_SECRET=$(cat /run/secrets/env) \
yarn
This statement does two things:
- It mounts the environment variable assigned to the "env" ID that was passed to the build command, and mounts it as a file, which by default would be placed in
/run/secrets/myId
(env
in this example). - It assigns the contents of the file to an environment variable that will only be available in that line of the Dockerfile (so you will need to mount it multiple times if you need it in different places). So yarn will hace access to it during the installation of the NodeJS packages.
Using this technique, you can mount several environment variables, but as far as I could figure out, you can only mount one per RUN statement. Maybe there is a way to overcome this limitation, but I did not have time to investigate further.