In this tutorial, we will set up a GitHub Actions workflow to build a Docker image for a sample Node.js application and push it to the GitHub Container Registry (GHCR). This is particularly useful for automating the CI/CD pipeline for containerized applications.


Step 1: Prerequisites

  1. GitHub Account: Ensure you have a GitHub account and an existing repository.
  2. GitHub Container Registry Access: Enable access to the GitHub Container Registry in your account.
  3. Docker Installed (Optional): Install Docker locally to test the image if needed.

Step 2: Create a Sample Node.js Application

Create a simple Node.js application to containerize.

Directory Structure

sample-node-app/
├── app.js
├── package.json
└── Dockerfile

app.js

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello, GitHub Container Registry!');
});

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

package.json

{
  "name": "sample-node-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.2"
  },
  "scripts": {
    "start": "node app.js"
  }
}

Dockerfile

# Use Node.js LTS as the base image
FROM node:lts-alpine

# Set the working directory
WORKDIR /app

# Copy package files and install dependencies
COPY package.json package-lock.json ./
RUN npm install

# Copy application code
COPY . .

# Expose the application port
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

Step 3: Configure GitHub Actions Workflow

Create a workflow file to automate building and pushing the Docker image.

File Path: .github/workflows/docker-publish.yml

name: Build and Push Docker Image

on:
  push:
    branches:
      - main  # Trigger workflow on pushes to the main branch

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      # Checkout the repository code
      - name: Checkout code
        uses: actions/checkout@v3

      # Log in to GitHub Container Registry
      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ secrets.GITHUB_ACTOR }}
          password: ${{ secrets.GITHUB_TOKEN }}

      # Build the Docker image
      - name: Build Docker image
        run: |
          docker build -t ghcr.io/${{ github.repository_owner }}/sample-node-app:latest .

      # Push the Docker image to GitHub Container Registry
      - name: Push Docker image
        run: |
          docker push ghcr.io/${{ github.repository_owner }}/sample-node-app:latest

Step 4: Test the Workflow

  1. Commit and Push Changes:
   git add .
   git commit -m "Add CI workflow to build and push Docker image"
   git push origin main
  1. Verify Workflow Execution:
  • Navigate to the Actions tab in your GitHub repository.
  • Confirm that the workflow runs successfully.
  1. Check the Image in GitHub Container Registry:
  • Go to https://github.com/<your-username>?tab=packages.
  • Verify that the Docker image is listed under the Packages section.

Step 5: Pull and Test the Image Locally

You can test the image locally by pulling it from GHCR.

docker pull ghcr.io/<your-username>/sample-node-app:latest
docker run -p 3000:3000 ghcr.io/<your-username>/sample-node-app:latest

Access the app at http://localhost:3000.


Conclusion

In this tutorial, you’ve learned how to:

  1. Create a simple Node.js application.
  2. Write a Dockerfile to containerize the application.
  3. Configure GitHub Actions to build and push the image to GHCR.
  4. Test the pushed image locally.

You can now integrate this process into your CI/CD pipeline for automated container builds.