This is a quick writeup on how to dockerize a nodejs application, using Github Actions to automatically build when you push to the main branch, and publish your image to Github Container Registry (ghcr)

Create the dockerfile

Inside your nodejs app run: touch dockerfile

Add the folllowing code (change the port number, nodejs version, and entrypoint):

FROM node:18

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 3000 #my app.js says express must run on port 3000
CMD [ "node", "app.js" ]

Build locally to test

Now lets build the image:

docker build . --tag <your tag here>

After a while your build is done. Run docker image ls and you should see your image

Start up a container using this image: docker run -p 50001:3000 -d <your tag here>

If your container does not start, run docker container ls -a and see if it exited. If it did, run the above command without the “-d” switch to get the error message.

Now you can access your node app on the port you specified when you started your container.

Here is a docker compose file for this image:

version: "3"
services:
  nodejs_webhook:
    image: 'nodejs_webhook'
    restart: unless-stopped
    ports:
      - '50001:3000'

Github Action to automatically build and push to ghcr

Here is the Github Actions code to automatically build and push your container to ghcr

name: auto_build_dockerfile

on:
  push:
    branches: main

jobs:
  login_build_push:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
    steps:
      -
        name: Login to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          #token is auto generated for you
          password: ${{ secrets.GITHUB_TOKEN }} 
      -
        name: Checkout Before Build
        uses: actions/checkout@v3
      -    
        name: Build Image
        run: |
              docker build . --tag ghcr.io/${{github.actor}}/${{ github.event.repository.name }}:latest
              docker push ghcr.io/${{github.actor}}/${{ github.event.repository.name }}:latest

We have 3 steps:

  • Login to ghcr
  • Checkout your code
  • Now build your image and push to your ghcr
  • The token we are using gets auto generated

Notice that in set the job we set the permissions otherwise you will get this error “denied: installation not allowed to Create organization package

Where are your built images?

In our action we said our image should be called: ghcr.io/${{github.actor}}/${{ github.event.repository.name }}:latest

In my case it will be: https://ghcr.io/necrolingus/nodejs_webhook_listener:latest

Or you can go to your packages using the Github website in the following ways:

You can also find them under: https://github.com/your_username