It’s always been a challenge defining and accessing secrets when using Dockerfiles. There wasn’t really any good and safe solution of for example accessing a private repository or service because removing environment variables and remove secret files that are part of the build would still be available in the metadata of the image.
Even when using of multi-stage builds the user still needs to be sure to clean all the secrets and secure values and even after doing that, the secret files are still accessible via the local build cache.
This is now finally being addressed in Docker 18.09. Let’s see how this works in practice.
Once updated to
18.09, the first thing to do to use build secrets is to enable BuildKit backend which is not enabled by default as of now. This is easily done by setting an environment variable
Being able to safely use secrets during builds is a result of new features introduced in the latest version of buildkit which is the possibility to use mounts in
RUNcommands for Dockerfiles.
To use this new feature instead of the default one, you need to define the builder image with a syntax directive as a first line of the Dockerfile, pointing to the container image you wish to use. Secrets are currently not enabled in the stable channel of external Dockerfiles, so you need to use one of the releases in the experimental channel, e.g.
When building images and a
RUN command in your Dockerfile requires a secret, you should use a
--mount flag on that command, specifying what secret the command needs and where to mount it. The mount flag accepts a comma-separated structure similar to the
--mountflag when using
# syntax=docker/dockerfile:1.0.0-experimentalFROM alpineRUN --mount=type=secret,id=accelero.key command-to-run
By specifying the flag, it tells the command that it has access to a secret file on the path
/run/secrets/accelero.key. The secret is only exposed to the single command that defined the mount, not to the other parts of the build. All secrets by default are mounted to the path
/run/secrets but you can specify any path you want using the “target” key.
Docker CLI currently supports exposing secrets from local files from the client using the
docker build --secret id=accelero.key,src=path/to/accelero.key .
There’s no limitation to using a single secret and can use as many as you want by specifying different IDs.
If the Dockerfile author defines that a
RUN instruction can use a secret but the user invoking a build does not provide it, the secret is ignored and no file is mounted to the path. If this is not the behavior that you want, you can use the “required” key to mark that a build should fail if no value is passed.
# syntax=docker/dockerfile:1.0.0-experimentalFROM alpineRUN --mount=type=secret,id=accelero.key,required <command-to-run>
A secret file is automatically mounted only to a separate tmpfs filesystem to make sure that it does not leak to the final image nor to the next command and that it does not remain in the local build cache.
The secret values are also excluded from the build cache calculations to avoid anyone from using the cache metadata from getting information about the secret value.
This new feature will help operators use Dockerfiles better and make make your build pipeline more secure.
Get up & running on AWS, GCP, and Azure with DevOps best practices and world-class infrastructure in less than a week with Accelero. To gain access or for more info, feel free to reach out to us at email@example.com.