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.
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 .
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
.npmrcchanges, you can edit the project specific
.npmrcfile 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.
You will have to make a secret on GitHub called
CICD_NPMRC with the contents:
Similar to GitHub actions with private SPM dependencies, we can make an actions workflow that looks like this:
Some further reading about NPM and secrets in the new BuildKit can be found here, I used these resources to put together this solution:
As always, if you know of a better way to do something, please let me know!