Secrets with Docker and BuildKit (with NPM)
Posted Tuesday, April 6, 2021.In a previous post, Docker with private NPM dependencies we discussed how to inject an NPM token into the Dockerfile for private dependency resolution.
Requirements can be found in previous post SSH with Docker and BuildKit. Here is how to adjust the previous project to use the --secret
option for both local builds and on GitHub actions.
Dockerfile/Project Changes
Original
From Docker with private NPM dependencies, our Dockerfile looked as such:
We created a file in the root of the project called .npmrc-deploy
that looked as such:
This could be built using docker build --build-arg NPM_TOKEN="$(cat ~/.npm/github_token)" -t hiimtmac/cool-app .
Updated
Using the new --secret
option, we can adjust our Dockerfile to look like this:
In this case we will adjust the .npmrc
setup. Change .npmrc-deploy
's filename to just .npmrc
and delete the auth token line so it only specifies where the registries are located:
Additionally, make a new file at ~/.npm/github_npmrc
with the contents of the old token file (~/.npm/github_token
) but with the auth token line:
We are breaking these up so the secret can be leveraged on GitHub actions and locally without the need to be changed (unless you invalidate the token) as the project changes, and can remain in source control (no token in it, only the dependency locations). This way, if the dependencies change for this specific project and hence the project
.npmrc
changes, you can edit the project specific.npmrc
file and not have to change the secret both locally and on GitHub.
This could be built using docker build --secret id=github,src=$HOME/.npm/github_npmrc -t hiimtmac/cool-app .
. Any RUN
command that needs secret access (in this case the RUN yarn && yarn build
command) needs to have --mount=type=secret,id=...
in the beginning.
The authorization token will be picked up from /root/.npmrc
where it is by default expected to be found, and the dependency locations will be picked up from the local .npmrc
file. The benefit here is that because the secret info was injected as a BuildKit secret, we dont have to worry about that file being leaked and part of a layer where it can be inspected later.
GitHub Actions
Secret
You will have to make a secret on GitHub called CICD_NPMRC
with the contents: //npm.pkg.github.com/:_authToken=SECRET_FROM_GITHUB_TOKEN_FILE_HERE
Workflow
Similar to GitHub actions with private SPM dependencies, we can make an actions workflow that looks like this:
In Closing
Some further reading about NPM and secrets in the new BuildKit can be found here, I used these resources to put together this solution:
- https://docs.docker.com/develop/develop-images/build_enhancements/
- https://medium.com/@mtiller/building-docker-images-simply-and-securely-using-private-npm-registries-2c9f6694737b
- https://www.alexandraulsh.com/2019/02/24/docker-build-secrets-and-npmrc/
- https://www.alexandraulsh.com/2018/06/25/docker-npmrc-security/
As always, if you know of a better way to do something, please let me know!
Tagged With: