Build Node docker image with Azure Devops Npm Registry and Azure Devops Pipelines
This page will explain how to build a docker image of a Node.Js application, that uses a private dependency stored in Azure Devops Artifact Npm Registry.
Note : I will not explain here how to publish a library to an Azure devops Artifact NPM Registry.
As explained in the Azure Documentation, in order to use a dependency from Azure Devops Npm Registry, you will need to add an
.npmrc file with the url of the registry.
This Documentation Get started with npm packages in Azure Artifacts will detail how to authenticate and configure Azure Devops NPM Registry.
Of course you will have to authenticate from your build execution in order to download the private dependencies.
If you use the Npm@1 task, your task will be automatically authenticated. Azure Pipeline will inject credentials automatically.
- task: Npm@1 displayName: Install NPM Dependencies inputs: command: install workingDir: $(System.DefaultWorkingDirectory)/path/to/node-application
After the execution of this task, you can use npm script and it will be authenticated (as long as you run it in the same job, ie, the same agent).
Pipeline example :
variables: node_version: 16.19.1 pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: $(node_version) - task: Npm@1 displayName: Install NPM Dependencies inputs: command: install workingDir: $(System.DefaultWorkingDirectory)/path/to/node-application - script: npm run test workingDirectory: $(System.DefaultWorkingDirectory)/path/to/node-application displayName: 'Execute unit tests'
Now imagine you want to build a docker image of your code. As you will have to run an
npm install task during the docker build, you will need to have credentials inside the docker image.
Here is the Dockerfile of my application (this is a typescript application)
FROM node:18.12-alpine As BUILD WORKDIR /app COPY tsconfig.json . # A wildcard is used to ensure both package.json AND package-lock.json are copied COPY package*.json ./ # Copy Authentication COPY .npmrc . RUN npm ci COPY . . RUN npm run build FROM node:18.12-alpine WORKDIR /app COPY --from=BUILD /app/package*.json ./ COPY --from=BUILD /app/dist dist # Copy Authentication COPY --from=BUILD /app/.npmrc . RUN npm ci --production # Remove Authentication as it should not be in the final docker image RUN rm -f .npmrc EXPOSE 3000 CMD ["npm","start"]
As you can see, we specifically inject the
.npmrc file inside the image (then remove it).
It is important to remove the
.npmrcfile from the image published.
In order to create the
.npmrc file you can inject you will need to inject credentials inside the file.
For that you can use the npmAuthenticate@0 task jsut before the docker build :
- task: npmAuthenticate@0 inputs: workingFile: $(System.DefaultWorkingDirectory)/path/to/node-application/.npmrc - task: Docker@1 name: docker_build_image displayName: 'Docker: Build image' inputs: azureSubscriptionEndpoint: 'Your Service Connetion' azureContainerRegistry: 'my-acr.azurecr.io' buildContext: path/to/node-application dockerFile: 'path/to/node-application/Dockerfile' imageName: my-application:$(Build.BuildNumber) includeLatestTag: true
I hope this quick article was helpfull, feel free to comment, or react, and if you like … say and share 😃