Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save oelbaga/5019647715e68815c602ff05cff2416e to your computer and use it in GitHub Desktop.
Save oelbaga/5019647715e68815c602ff05cff2416e to your computer and use it in GitHub Desktop.
Setup NextJS app on Digital Ocean Ubuntu server Full Terminal Commands Step by Step
#Setup NextJS on Ubuntu server (Digital Ocean, EC2,...) Terminal Commands
#based on my YouTube video
#Recommended: An ubuntu server with at least 2 GB memory to handle npm run build
#login to server
ssh root@ip_address
#Upgrade Server - may take a few minutes
sudo apt update
sudo apt upgrade
#Install NGINX and Certbot
sudo apt install nginx certbot python3-certbot-nginx
#Allow Firewall Access
sudo ufw allow "Nginx Full"
ufw allow OpenSSH
ufw enable
#Install NPM - may take a couple of minutes
apt install npm
#install nodejs
#Option 1: install nodejs with nvm
curl -o- | bash
exec $SHELL
nvm install --lts
nvm install 20 #or version of choice
nvm use 20
nvm alias default 20
#Option 2:
curl -fsSL | sudo -E bash -
sudo apt-get install -y nodejs
#Install pm2
npm install -g pm2
#Check pm2 is working
pm2 status
cd /root/.ssh
ssh-keygen -t rsa -b 4096 -C ""
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/
#add public key to github repo settings > deploy key [or add to your profile settings > SSH so you can pull from all repos]
#go to www root
cd /var/www
#Create NextJS App or clone here
Option 1: npx create-next-app@latest name_of_app
Option2: clone with a specific branch. [You need SSH permissions from above for this].
A: git clone
or B (by specifying a branch): git clone -b <branch-name-optional> <local-name-desired-optional>
#note the name of the directory created for later to launch pm2 app
#Go inside new app directory
cd name_of_app
#Install npm modules for app
npm i
#Build it
npm run build
#Create NGINX config file and edit it
cd /etc/nginx/sites-available
touch name_of_app
nano name_of_app
#Syslink the file in sites-enabled
sudo ln -s /etc/nginx/sites-available/name_of_app /etc/nginx/sites-enabled/name_of_app
#make Sure NGINX file is good
nginx -t
#remove the default config files
cd /etc/nginx/sites-available
rm default
cd /etc/nginx/sites-enabled
rm default
#restart NGINX to reload config files
systemctl restart nginx
#Go to site directory and launch it with pm2
cd /var/www/name_of_app
#launch app with pm2
#Option 1:
pm2 start npm --name name_of_app -- start
#Option 2: if you need to launch on a different port. It seems this port should match what's used in the server block.
pm2 start npm --name nest -- start -- --port=3001
#save pm2 list
pm2 save
#pm2 restart on reboot
pm2 startup
#Create SSL with letsencryot
sudo certbot --nginx -d -d
#redirect site to www version
Go back in server block where the domain is managed by certbot and add www. To the redirect.
————— helpful commands ————
pm2 start npm --name name_of_app -- start (make sure you're inside the site's directory first)
systemctl restart nginx (restart NGINX)
sudo certbot --nginx -d (Add SSL)
#nginx config file for Nextjs App
#place in /etc/nginx/sites-available/name_of_config_file
server {
listen 80;
server_name; #if no domain you can use server ip until then
gzip on;
gzip_proxied any;
gzip_types application/javascript application/x-javascript text/css text/javascript;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_min_length 256;
location /_next/static/ {
alias /var/www/name_of_app/.next/static/;
expires 365d;
access_log off;
location / {
proxy_pass; #change ports for second app i.e. 3001,3002
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
1. Allow pulling from GitHub onto Digital ocean (if not done already).
- Create a new id_rsa key on your droplet
cd /root/.ssh
ssh-keygen -t rsa -b 4096 -C ""
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/
- add public key to git hub repo settings > deploy key [or add to your profile settings > SSH so you can pull from all repos]
- Now clone the entire repo for the first time under /var/www
2. Setup auto-deployment from GitHub commits to ubuntu server with Github actions
- local terminal ssh
cd .ssh
ssh-keygen -t rsa -b 4096 -C ""
- Copy that key to add to the server
cat ~/.ssh/
- Add public key to .ssh on ubuntu server
cd /root/.ssh
nano authorized_keys
- Copy that private key to add to GitHub
cat ~/.ssh/id_rsa
- Add private key Github repo
Settings > Secrets > Actions > New repository secret. Label: SSH_PRIVATE_KEY
Configure GitHub Actions with a deploy yml file:
- In your repository, create a new directory .github/workflows with a file called deploy.yml.
[SEE yml FILE] #
# Update to match your values: branch_name, app_name, SSH key name on GitHub from previous step if changed, server ip, username, port, and server Node pathname (using 'which pm2' on server to get path)
name: Deploy Next.js App
- branch_name # Change to your specific branch
# - deployprod # Additional branch for deployment
runs-on: ubuntu-latest
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
node-version: "20"
- name: Check Node.js version
run: node -v
- name: Set up SSH
uses: webfactory/ssh-agent@v0.5.1
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Deploy to DigitalOcean
TARGET_DIR: /var/www/folder_name
APP_NAME: app_name #should match the name of the server block
PORT: 3000
#if multiple deploys are needed from different branches
#TARGET_DIR: ${{ github.ref == 'refs/heads/deploytest' && '/var/www/folder_name' || github.ref == 'refs/heads/deployprod' && '/var/www/another-location' }}
#APP_NAME: ${{ github.ref == 'refs/heads/deploytest' && 'folder_name' || github.ref == 'refs/heads/deployprod' && 'folder_name_2' }}
#PORT: ${{ github.ref == 'refs/heads/deploytest' && '3000' || github.ref == 'refs/heads/deployprod' && '3001' }}
run: |
ssh -o StrictHostKeyChecking=no $USERNAME@$HOST << EOF
export PATH=/root/.nvm/versions/node/v20.12.0/bin:$PATH #'which pm2' command on terminal will give the right path
git pull origin ${GITHUB_REF#refs/heads/}
npm install
npm run build
if pm2 list | grep -q $APP_NAME; then
echo "Restarting application: $APP_NAME"
pm2 restart $APP_NAME
echo "Starting application: $APP_NAME"
pm2 start npm --name $APP_NAME -- start -- --port=$PORT
pm2 save
Copy link

Hello, thank you for your good teaching

I have a problem, I install correctly, but when I want to update, I have a problem, I have to delete all the items from the beginning and run npm i and npm run build again.
What should I do to update?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment