Devops

CI/CD pipeline for Next.js applications using GitHub Actions and docker

A step-by-step guide to setting up a CI/CD pipeline for Next.js applications using GitHub Actions and Docker.

CI/CD pipeline for Next.js applications using GitHub Actions and docker

Image of Amardeep Ranjan
Published on November 2, 2024
6 min read

In this blog, we will set up a CI/CD pipeline for Next.js applications using GitHub Actions and Docker. We will also deploy the application to digital ocean droplet.

Prerequisites

  • A GitHub account
  • A Next.js application
  • A Digital Ocean account
  • Docker installed on your local machine
  • A Domain(optional)

I'll be using a sample Next.js application for this blog. we will gonna dockerize it and use docker hub to store the docker image. we will use GitHub actions to build the docker image and deploy it to the digital ocean droplet. It's a simple process and you can follow along. If you have any questions, feel free to ask in the comments.

Dockerize the Next.js application

First, we need to dockerize the Next.js application. Create a Dockerfile in the root of your Next.js application and add the following content:

Dockerfile

FROM node:18-alpine AS build

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm install

COPY . .

RUN npm run build

FROM node:18-alpine AS production

WORKDIR /app

COPY --from=build /app/.next ./.next
COPY --from=build /app/package.json ./
COPY --from=build /app/public ./public
COPY --from=build /app/node_modules ./node_modules

EXPOSE 3000

ENV NODE_ENV production

CMD ["npm", "start"]

This Dockerfile does the following:

  • It uses the official Node.js image as a base.
  • It sets the working directory inside the container.
  • It copies the package.json and package-lock.json files to the working directory.
  • It installs the dependencies.
  • It copies the rest of the application to the working directory.
  • It builds the Next.js application.
  • It uses another stage for production to keep the image small.
  • It sets the working directory in the new stage.
  • It copies the built files from the build stage.
  • It exposes the port that the Next.js app runs on.
  • It sets the environment variable for production.
  • It specifies the command to run the Next.js app.

Create a GitHub repository

Create a new GitHub repository for your Next.js application. You can do this by clicking on the "New" button on the GitHub homepage and following the instructions. Once you have created the repository, push your Next.js application code to the repository. You can do this by running the following commands in your terminal:

git remote add origin
git branch -M main
git push -u origin main

Set up Docker Hub

Next, we need to set up Docker Hub to store the Docker image. Create a Docker Hub account if you don't already have one. Once you have created the account, create a new repository for your Next.js application. You can do this by clicking on the "Create Repository" button on the Docker Hub homepage and following the instructions.

Build and push the Docker image

Build the Docker image for your Next.js application by running the following command in your terminal:

docker build -t my-app .

This command builds the Docker image with the tag my-app. Next, push the Docker image to Docker Hub by running the following command in your terminal:

docker tag my-app:latest my-docker-username/my-app:latest
docker push my-docker-username/my-app:latest

Replace my-docker-username with your Docker Hub username. This command tags the Docker image with your Docker Hub username and pushes it to Docker Hub.

Set up Digital Ocean droplet

Next, we need to set up a Digital Ocean droplet to deploy the Next.js application. Create a new droplet on Digital Ocean by following the instructions on the Digital Ocean website. Once you have created the droplet, SSH into the droplet and install Docker by running the following commands:

ssh root@your-droplet-ip
apt update
apt install docker.io

Replace your-droplet-ip with the IP address of your Digital Ocean droplet. This command installs Docker on the droplet.

Set up GitHub Actions

Next, we need to set up GitHub Actions to build the Docker image and deploy it to the Digital Ocean droplet. Create a .github/workflows/main.yml file in the root of your GitHub repository and add the following content:

main.yml

name: Deploy to DigitalOcean Droplet

on:
  push:
    branches:
      - main # Adjust the branch as needed

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to Docker Hub
        run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin

      - name: Build and Push Docker Image
        run: |
          docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/my-app .
          docker tag ${{ secrets.DOCKER_HUB_USERNAME }}/my-app:latest ${{ secrets.DOCKER_HUB_USERNAME }}/my-app:latest
          docker push ${{ secrets.DOCKER_HUB_USERNAME }}/my-app:latest

      - name: Set up SSH
        uses: webfactory/ssh-agent@v0.5.3
        with:
          ssh-private-key: ${{ secrets.DIGITALOCEAN_SSH_KEY }}

      - name: Add DigitalOcean Droplet to known_hosts
        run: |
          echo "${{ secrets.DROPLET_SSH_PUBLIC_KEY }}" >> ~/.ssh/known_hosts

      - name: Deploy to DigitalOcean Droplet
        run: |
          ssh root@${{ secrets.DIGITALOCEAN_DROPLET_IP }} "docker pull ${{ secrets.DOCKER_HUB_USERNAME }}/my-app:latest && docker ps -q | xargs -r docker stop && docker run -d -p 3000:3000 ${{ secrets.DOCKER_HUB_USERNAME }}/my-app:latest"

You will need to add the following secrets to your GitHub repository:

  • DOCKER_HUB_USERNAME: Your Docker Hub username
  • DOCKER_HUB_PASSWORD: Your Docker Hub password
  • DIGITALOCEAN_SSH_KEY: Your Digital Ocean SSH private key
  • DROPLET_SSH_PUBLIC_KEY: Your Digital Ocean droplet SSH public key
  • DIGITALOCEAN_DROPLET_IP: Your Digital Ocean droplet IP address

Understanding the GitHub Actions workflow

This GitHub Actions workflow does the following:

  • It listens for pushes to the main branch.
  • It checks out the code from the repository.
  • It sets up Docker Buildx for building multi-architecture images.
  • It logs in to Docker Hub using the provided credentials.
  • It builds the Docker image and pushes it to Docker Hub.
  • It sets up SSH for connecting to the Digital Ocean droplet.
  • It adds the Digital Ocean droplet to the known hosts.
  • It deploys the Docker image to the Digital Ocean droplet.

Conclusion

In this blog, we set up a CI/CD pipeline for Next.js applications using GitHub Actions and Docker. We also deployed the application to a Digital Ocean droplet. This is a simple and effective way to automate the deployment process and ensure that your application is always up to date. If you have any questions or feedback, feel free to leave a comment below. Happy coding!