In the ever-evolving landscape of software development, streamlining workflows is paramount to success. In this article, we’ll explore how to leverage the powerful combination of GitHub Actions, Docker, and the GitHub npm Package to automate and optimize your development processes. From automating CI/CD pipelines to seamlessly managing dependencies, join us as we delve into the world of automation and discover how these tools can revolutionize your development workflow.
Github, NPM registry, Docker
In today’s software development landscape, GitHub stands out as the most popular platform for storing and managing Git repositories. Beyond its fundamental role in version control, GitHub offers additional functionalities, including the capability to host private NPM registry. This feature facilitates the storage and sharing of JavaScript and TypeScript code among projects and teams, enhancing collaboration and code reusability across your organization.
GitHub Actions allows you to automate tasks for your projects, such as checking code styles, running tests, building Docker images, deploying to different environments, and more.
When discussing Docker, it’s common practice to build your application, library, or any code within a specific Docker image. Within this image, you can define the version of the Node machine, as well as any external resources and libraries required during the build process. This approach offers remarkable convenience, as it eliminates the need to rely on a specific PC or virtual machine with all the necessary setup. Instead, you can prepare the environment at the Docker level once and reuse it consistently across different machines and environments, ensuring consistency and reproducibility throughout your development workflow.
However, a challenge arises when you attempt to build your application within Docker and it requires an npm library stored in your GitHub NPM private registry. Moreover, this process should be feasible within GitHub Actions. In this article, I will guide you through the setup process for achieving this seamlessly!
How to Utilize a Private GitHub Registry?
Firstly, let’s begin with a simple scenario involving routing. Picture a project with a dependency from a private NPM registry.
{
...
"dependencies": {
...
"@targsoft/private-lib": "^1.0.0",
...
}
...
}
First of all, you need to generate a new GitHub Token. You can generate a token in your GitHub account settings at https://github.com/settings/tokens. Make sure to add the ‘read:packages’ scope to your token.
Once you’ve obtained your token, you have two options:
Add your token to your global npm configuration. Open your terminal and run the following commands:
npm login --registry=https://npm.pkg.github.com --scope=@targsoft
login: your username password=TOKEN
where scope is your registry name
Alternatively, you can create an .npmrc file next to your package.json file with the following content:
@targsoft:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=TOKEN
always-auth=true
This should do the trick, and your global npm will fetch the library from the private registry. Try running ‘npm install’ to see if it works!
How to use a Private GitHub Registry inside Docker?
Okay, so it’s pretty clear how to use the GitHub registry from your local machine. But what if you have a Dockerfile that builds your application within itself and then runs the application? For example, it could be a small web application with nginx as the web server.
FROM node:20-alpine AS build
WORKDIR /opt
COPY ./package.json ./yarn.lock /opt/
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc yarn install --frozen-lockfile
COPY . .
RUN yarn audit --omit=dev
RUN yarn build
FROM nginx:1.25.4-alpine AS runtime
COPY --from=build /opt/dist/targpatrol-main-frontend /usr/share/nginx/html
COPY docker/nginx.conf /etc/nginx/nginx.conf
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/assets/env.template.js > /usr/share/nginx/html/assets/env.js && exec nginx -g 'daemon off;'"]
The trick here is to pass secrets into your Dockerfile so that npm inside Docker can access the GitHub private registry.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc yarn install --frozen-lockfile
As you can see, we mount secrets before installing packages. This ensures that npm has the necessary credentials to fetch dependencies from the private registry.
The Docker Compose file will resemble the following:
version: '3.9'
secrets:
npmrc:
file: ./.npmrc
....
services:
targpatrol-main-frontend:
build:
context: ../../targpatrol-main-frontend
secrets:
- npmrc
container_name: targpatrol-main-frontend
restart: always
networks:
- targpatrol-docker-network
.npmrc is the same file we used to fetch library using global npm.
@targsoft:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=TOKEN
always-auth=true
Now you can run try to build the container:
docker compose up --build --force-recreate
How to use Github Action to build Docker image?
Okay, now that we’re able to build the Docker image on our local machines, what if we want to use GitHub Actions to build the image? Here’s how we need to do it.
name: targpatrol-main-frontend-pr-opened
...
jobs:
build-and-test:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ${{ env.SERVICE }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: '20.x'
registry-url: 'https://npm.pkg.github.com'
scope: '@targsoft'
- name: Install npm packages
run: yarn install --frozen-lockfile
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Lint
run: yarn lint
- name: Audit
run: yarn audit --omit=dev
- name: Build
run: yarn build
- name: Docker Build and push to AWS ECR
uses: docker/build-push-action@v5
with:
context: ${{ env.SERVICE }}
file: ${{ env.SERVICE }}/Dockerfile
secrets: |
"npmrc=${{ secrets.NPMRC_SECRET_FILE }}"
push: false
This is an example of how to set up Node.js inside a GitHub action. The NPM_TOKEN should be set up at the repository or organization level. NPMRC_SECRET_FILE is the GitHub Action secret that contains the same content as the .npmrc file.
Don’t forget about Dependabot
If you are using Dependabot to watch your packages versions you have to create separate secrets for it because it won’t take secrets from your Github Actions.
Conclusion
In conclusion, the integration of GitHub Actions, Docker, and the GitHub npm Package presents a powerful solution for automating workflows in software development. By harnessing these tools, developers can streamline their processes, increase productivity, and ensure consistency across projects and teams. From automating builds and deployments to managing dependencies seamlessly, the possibilities are endless. As technology continues to evolve, mastering these tools will become increasingly essential for staying competitive in the ever-changing landscape of software development. So, dive in, experiment, and discover the endless possibilities of automating your workflows with GitHub Actions, Docker, and the GitHub npm Package.
Top comments (0)