CI/CD Pipeline
Introduction
In my last blog, I shared how I got started with deploying a Next.js app on an EC2 instance using:
EC2 for hosting
NVM for Node version management
PM2 for keeping the app alive in the background
Nginx as a reverse proxy to serve the app directly on port 80
That was a big step, but manually pulling code, building, and restarting the app isn’t scalable. Imagine having to SSH into the server and repeat these steps every time you push new code — it’s time-consuming and error-prone.
This is where CI/CD (Continuous Integration and Continuous Deployment) comes in.
Explanation of CI/CD pipeline
CI/CD stands for Continuous Integration, Continuous Deployment and this is used to push any code changes directly to the production/dev environment.
Setting Up GitHub Actions
I created a GitHub Actions workflow to automate my deployment:
Inside my repo, I added a
.github/workflows/deploy.ymlfile.Wrote a workflow that triggers on
pushto the main branch.It connects to my EC2 instance via SSH, pulls the latest code, installs dependencies, builds the Next.js app, and restarts it with PM2.
Example snippet (simplified):
name: Deploy to EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy via SSH
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_KEY }}
script: |
cd /home/ubuntu/my-app
git pull origin main
npm install
npm run build
pm2 restart next-app
With this in place, all I have to do is push to GitHub → and my EC2 server updates automatically. Magic.



