Logo

dev-resources.site

for different kinds of informations.

From Code to Cloud: Builds Next.js on GitHub Actions, straight to production

Published at
1/6/2025
Categories
nextjs
githubactions
devops
cicd
Author
AJAY SHRESTHA
Categories
4 categories in total
nextjs
open
githubactions
open
devops
open
cicd
open
From Code to Cloud: Builds Next.js on GitHub Actions, straight to production

By maintaining, the CI/CD pipelines for build, test, and deployment processes, teams can ensure faster and more reliable releases, reduce the chance of human error, and minimize downtime.
We'll explore how to create a simple CI/CD pipeline to build a Next.js application with GitHub Actions and deploy the built files to an AWS EC2 instance.

Why Build Locally on GitHub Actions?

Traditionally, teams might clone and build their Next.js applications directly on the production server. However, this approach can create several issues:

  • Long Build Times: Running the build process on the server can increase CPU usage, slowing down other processes running on the production instance.
  • Error Prevention: If the build fails in production, it can lead to partial or broken deployments.
  • Wasted Resources: Production servers are often optimized to run applications rather than handle heavy builds or compute tasks.
  • Isolation: Keeps the build process separate from the production environment, reducing the risk of server instability.

Moving the build process to GitHub Actions lets you offload compute-intensive tasks to GitHub’s cloud infrastructure. That means your production server only receives fully built and tested files.

Setting Up the GitHub Actions Workflow

Below is the sample file .github/workflows/build-and-deploy.yml that you can place in your project to automate your Next.js app deployment using github action.

name: Build and Deploy Next.js in AWS EC2 Instance

on:
  push:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # 1. Check out code
      - name: Check out repository
        uses: actions/checkout@v3

      # 2. Set up Node.js 22 environment
      - name: Use Node.js 22
        uses: actions/setup-node@v3
        with:
          node-version: 22

      # 3. Install dependencies
      - name: Install dependencies
        run: npm install

      # 4. Create .env file (if you need environment variables at build time)
      - name: Create .env file
        run: |
          echo "AUTH_SECRET=${{ secrets.AUTH_SECRET }}" >> .env
          echo "DOMAIN=${{ secrets.DOMAIN }}" >> .env
          echo "BASE_URL=${{ secrets.BASE_URL }}" >> .env

      # 5. Build your Next.js application
      - name: Build
        run: npm run build

      # 6. Configure SSH (add host key, set up private key)
      - name: Configure SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts

      # 7. Transfer the .next folder to EC2 using SCP
      - name: Deploy to EC2
        run: |
          # 1. Remove the old .next folder on the remote server
          ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} \
            "rm -rf /home/${{ secrets.EC2_USER }}/app/.next"

          # 2. Copy the new .next folder from your Actions workspace to the remote server
          scp -o StrictHostKeyChecking=no -r .next ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USER }}/app

      # 8. Restart the Node.js server
      - name: Restart PM2 with pm2.json
        run: |
          # SSH into the server, navigate to the project directory and restart using pm2.json
          ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} \
            "cd /home/${{ secrets.EC2_USER }}/app && pm2 stop pm2.json || true && pm2 start pm2.json"

Explanation of Each Step

  • Check out Repository: Uses actions/checkout@v3 to pull down the code from GitHub so the workflow can run your scripts.

  • Set up Node.js 22: Ensures the build environment uses Node.js version 22, aligning with your Next.js requirements.

  • Install Dependencies: Installs all npm packages required for your Next.js application.

  • Create .env File: Dynamically injects secrets (e.g., AUTH_SECRET, DOMAIN, etc.) into a .env file for the build step. GitHub encrypts these secrets at rest, protecting them from unauthorized access. Add keys as per your project's requirements.

  • Build Next.js App: Runs npm run build to produce the optimized production build, generating the .next folder.

  • Configure SSH: Adds your private key to the SSH agent and updates the known hosts. It ensures that your workflow can securely connect to the EC2 instance.

  • Deploy to EC2: Removes any existing .next folder on the remote server (housekeeping), and Securely transfers the newly built .next folder via scp.

  • Restart PM2: Stops the existing PM2 process if running, then restarts it using a preconfigured pm2.json to apply updates with minimal downtime.

Configuring SSH

To securely deploy your Next.js application to an AWS EC2 instance using GitHub Actions, you need to establish a secure SSH connection between GitHub and your EC2 server. This involves locally generating an SSH key pair, adding the public key to your EC2 instance's authorized_keys, and storing the private key securely in GitHub Secrets.

1. Generate an SSH Key Pair Locally
First, create an SSH key pair on your local machine. This key pair will authenticate GitHub Actions with your EC2 instance.

# In Terminal (Linux)
ssh-keygen
(Follow the instructions provided)

2. Add the Public Key to EC2 Instance
To allow GitHub Actions to SSH into your EC2 instance, you need to add the generated public key to the authorized_keys file on your server.

# Access Your EC2 Instance
ssh [USER]@[EC2_PUBLIC_IP]

# Create the .ssh Directory (If It Doesn't Exist)
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# Add the Public Key to authorized_keys
vi ~/.ssh/authorized_keys
# paste the key into the authorized_keys

cat ~/.ssh/id_rsa.pub on your local machine. Copy the output and paste it into the authorized_keys file on your EC2 instance. Save and exit the editor.

3. Add the Private Key to GitHub Secrets
On your local machine, copy the contents of the private key cat ~/.ssh/id_rsa, Navigate to your github repository and follow the steps:

  • Click on the Settings tab then Click on Secrets and variables > Actions
  • Click on the New repository secret button, Name the secret EC2_SSH_KEY, paste the copied private key into value, and click on Add Secret

Same as above, add EC2_USER and EC2_HOST for ssh and required .env keys.

Implementing a CI/CD pipeline with GitHub Actions for your Next.js application provides a streamlined, automated, and reliable process from code push to production deployment. By building in GitHub Actions and transferring the final artifacts to your AWS EC2 instance, you reduce the computational overhead on your production server and mitigate the risk of failed builds causing downtime or broken deployments.

If you're new to next.js deployment, I've written a detailed guide on Deploying Next.js App in AWS EC2 with Nginx and PM2.

Featured ones: