This guide will help you set up a Next.js project to automatically deploy to an EC2 instance using GitHub Actions.
Use the following if you already have a project deployed on EC2. Otherwise, follow the detailed guide.
// EC2
sudo apt update
npm install pm2 -g
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/node" "/usr/local/bin/node"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/npm" "/usr/local/bin/npm"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/pm2" "/usr/local/bin/pm2"
// project directory
pm2 start npm -n deploy -- start
for custom port
pm2 start npm -n deploy -- start -- -p 3001
- Generate a SSH key in EC2 (skip if already have one):
ssh-keygen -m PEM
- Move the public key to authorized_keys:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
- Copy the private key content:
cat ~/.ssh/id_rsa
// Copy the content manually
-
In GitHub, navigate to Repository > Settings > Secrets and variables > Actions and create the following three secrets:
-
EC2_HOST
: Public IP of your EC2 instance -
EC2_USERNAME
: Username to SSH into EC2 -
EC2_PRIVATE_KEY
: Paste the private key content generated earlier.
-
Add the following code to .github/workflows/deploy.yml
in your project:
name: Deploy App to EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Rename .next to .next2
run: mv .next .next2
- name: Send .next2 to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: .next2
target: opub-deploy
- name: Update with new Build
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script: rm -rf opub-deploy/.next; mv opub-deploy/.next2 opub-deploy/.next; pm2 restart opub-deploy
Replace all instances
opub-deploy
with your project name in EC2.
Create a GitHub repository, for example: opub-deploy
.
- Generate a Next.js project:
npx create-next-app@latest opub-deploy
cd opub-deploy
npm install
- Add the following code to
.github/workflows/deploy.yml
in your project:
name: Deploy Next.js to EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Rename .next to .next2
run: mv .next .next2
- name: Send .next2 to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: .next2
target: opub-deploy
- name: Update with new Build
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script: rm -rf opub-deploy/.next; mv opub-deploy/.next2 opub-deploy/.next; pm2 restart deploy
Replace all instances
opub-deploy
with your project name in EC2.
- Initialize a Git repository:
git init
git add .
git branch -M main
git remote add origin git@github.com:CivicDataLab/opub-deploy.git
git commit -m "first commit"
git push -u origin main
- Create an EC2 instance with Ubuntu 20.04.
- Create a new key pair and download the
.pem
file. - Create a new security group with the following inbound rules:
- SSH (22) from anywhere
- HTTP (80) from anywhere
- HTTPS (443) from anywhere
- Custom TCP (3000) from anywhere
- Connect to the EC2 instance using SSH:
ssh -i "path/to/key.pem" username@publicIP
Install Node.js and npm using NVM:
sudo apt update
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Install PM2 globally:
npm install pm2 -g
Create symbolic links
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/node" "/usr/local/bin/node"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/npm" "/usr/local/bin/npm"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/pm2" "/usr/local/bin/pm2"
Clone your GitHub repository and navigate to its directory:
git clone https://github.com/CivicDataLab/opub-deploy.git
cd opub-deploy
Install the dependencies and start the server:
npm install
npm run build
pm2 start npm -n deploy -- start
for custom port
pm2 start npm -n deploy -- start -- -p 3001
- Generate a SSH key:
ssh-keygen -m PEM
- Move the public key to authorized_keys:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
- Copy the private key content:
cat ~/.ssh/id_rsa
// Copy the content manually
-
In GitHub, navigate to Repository > Settings > Secrets and variables > Actions
-
Create the following three secrets to allow GitHub to SSH into EC2:
-
EC2_HOST
: Public IP of your EC2 instance -
EC2_USERNAME
: Username to SSH into EC2 -
EC2_PRIVATE_KEY
: Paste the private key content generated earlier.
-
Now, every time you push to the main branch, the GitHub Actions workflow will build the project and deploy it to the EC2 instance without any manual intervention and downtime.