Hi I am a docker noob, so excuse me if this is a dumb question.
I want to build a npm package on dockerhub, but my package have private dependencies.
I try to authenticate by defining my NPM authToken as a build-time environment variable in my Dockerfile.
I thought a line like this in my Dockerfile should work:
ARG NPM_TOKEN=00000000-0000-0000-0000-000000000000
but I get a 404 error.
Will this strategy work, or is there another way for the build server to get access to my private repos?
Setting the NPM_TOKEN environment is not possible to authenticate with npm. See npm/npm#8356 for a more detailed description of the issue.
What you can do instead is the following:
FROM node:argon
ENV NPM_TOKEN "00000000-0000-0000-0000-000000000000"
RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
RUN npm install
CMD ['node' 'index.js']
Ah great, thanks for the quick response!
This npm blog post is really pretty misleading...
Is this still the recommended way to use npm private package with Docker?
In order for this to work, i need to leave NPM_TOKEN inside my code base.
For the record (and because this issue have pretty good google indexation), you can achieve it safely using build-args in your CI system.
Build command
docker build --build-arg NPM_TOKEN={you token here} -t image:tag .
Dockerfile
FROM node:7
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc && \
npm install && \
rm ~/.npmrc
You may still be interested @tuananh
@PuKoren exactly what I need. Many thanks.
Watch out! Your token is stored as a commit message in the docker history!
Read: https://blog.risingstack.com/private-npm-with-docker/ and https://docs.npmjs.com/private-modules/docker-and-private-modules
@VolleMelk what do you recommend?
If put in file and then removed in the same command it should not be kept into any layer
This is ok:
FROM node:7
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc && \
npm install && \
rm ~/.npmrc
but this is not:
FROM node:7
ARG NPM_TOKEN
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
RUN npm install
RUN rm ~/.npmrc
@PuKoren It's not about the layer, it's in the _commit message_:
Dockerfile:
FROM microsoft/dotnet-framework:3.5
ARG NPM_TOKEN
RUN echo //registry.npmjs.org/:_authToken=%NPM_TOKEN% > C:\\.npmrc
Run with
docker build --build-arg NPM_TOKEN=this_is_my_test_token .
Console output:
D:\docker\test> docker build --build-arg NPM_TOKEN=this_is_my_test_token .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM microsoft/dotnet-framework:3.5
---> a0edc80e79f8
Step 2/3 : ARG NPM_TOKEN
---> Using cache
---> 1f0b9e5e6fd6
Step 3/3 : RUN echo //registry.npmjs.org/:_authToken=%NPM_TOKEN% > C:\\.npmrc
---> Running in 4620a638f2ec
---> 0a1a95f7f471
Removing intermediate container 4620a638f2ec
Successfully built 0a1a95f7f471
So far so good (it's not interpolating the environment variable, showing %NPM_TOKEN% instead of the actual value). And because of the redirect output operator (>) we're not seeing the result of the echo command.
But when we check the docker history of said image with docker history --no-trunc 0a1a95f7f471
D:\docker\test> docker history --no-trunc 0a1a95f7f471
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:0a1a95f7f471 3 minutes ago |1 NPM_TOKEN=this_is_my_test_token cmd /S /C echo //registry.npmjs.org/:_authToken=%NPM_TOKEN% > C:\\.npmrc 16.1MB
sha256:1f0b9e5e6fd6 3 minutes ago cmd /S /C #(nop) ARG NPM_TOKEN 41kB
sha256:a0edc80e79f8 4 months ago cmd /S /C DISM /Online /Add-Package /PackagePath:C:\build\microsoft-windows-netfx3-ondemand-package.cab & DISM /Online /Add-Package /PackagePath:C:\build\patch\Windows10.0-KB3213986-x64.cab & rd /s /q C:\build 1.1GB
<missing> 4 months ago cmd /S /C #(nop) ADD dir:3cf624d67eb78708ae0d25961d5ee719003484c897ad88949ce7509ea2c43768 in \build 1.24GB
<missing> 4 months ago Install update 10.0.14393.1480 2.56GB
<missing> 11 months ago Apply image 10.0.14393.0 7.68GB
We can see the value of the NPM_TOKEN as a build argument.
Perhaps squashing the commits will solve this, but I haven't got any experience with that
Update: I built an image using the same Dockerimage using docker build --build-arg NPM_TOKEN=this_is_my_test_token --squash . but it's still in the docker history
I even altered the Dockerfile to accept another ARG MORE_TOKENS and re-ran the build:
docker build --build-arg NPM_TOKEN=this_is_my_test_token --build-arg MORE_TOKENS=this_is_not_my_test_token --squash .
Docker history:
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:e9c0dba588007aad59869af9e4b0577140fe63a317a4c266eecc77ce7a31bf9c 26 seconds ago 16.1MB merge sha256:b41440e2d6ca62e8d83f6453f00e3b52240dbc9869bbc1dda377eb1dc33770b0 to sha256:a0edc80e79f854bc3e2987e189e9ab253f0aef37448689d4279a0bfa0d3d4d55
<missing> 29 seconds ago |2 MORE_TOKENS=this_is_not_my_test_token NPM_TOKEN=this_is_my_test_token cmd /S /C echo //registry.npmjs.org/:_authToken=%NPM_TOKEN% > C:\\.npmrc
[.. more of the same here..]
@tuananh I didn't really have a solution for this, but then again I didn't really need the token during my _build_. I only need the token when running the container.
NPM interpolates environment variables inside .npmrc. I create an .npmrc file with
# [.. more Dockerfile here ..]
RUN echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
# [.. more Dockerfile here ..]
And I start the docker container with docker run --env NPM_TOKEN=this_is_my_token docker-image.
By using the docker run --env argument for secrets instead of the docker build ENV directive or docker build ARG directive with --build-arg argument has the following benefits:
Yes, you need to supply your NPM_TOKEN each time you start the docker container.. but safety first ;-)
Most helpful comment
Setting the
NPM_TOKENenvironment is not possible to authenticate with npm. See npm/npm#8356 for a more detailed description of the issue.What you can do instead is the following: