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- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
exec $SHELL
nvm install --lts
nvm install 20 #or version of choice
nvm use 20
nvm alias default 20
#Option 2:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
#Install pm2
npm install -g pm2
#Check pm2 is working
pm2 status
#[SETUP SSH KEY ON SERVER TO ALLOW CLONE AN EXISTING REPO ONTO YOUR DROPLET]
cd /root/.ssh
ssh-keygen -t rsa -b 4096 -C "username@email.com"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub
#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 git@github.com:username/repo_name.git
or B (by specifying a branch): git clone -b <branch-name-optional> git@github.com:username/repo_name.git <local-name-desired-optional>
#note the name of the directory created for later to launch pm2 app
ls
#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
[SEE OTHER GIST FOR CONFIG FILE (Server Block) CONTENTS]
#https://gist.github.com/oelbaga/5019647715e68815c602ff05cff2416e#file-02-nginx-config-file-for-nextjs-site
#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 domainname.com -d www.domainname.com
#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 domainname.com (Add SSL)
#nginx config file for Nextjs App
#place in /etc/nginx/sites-available/name_of_config_file
server {
listen 80;
server_name domainname.com www.domainname.com; #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 http://127.0.0.1:3000; #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 "your_email@example.com"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub
- 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 "oelbaga@newworldgroup.com"
- Copy that key to add to the server
cat ~/.ssh/id_rsa.pub
- 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] #https://gist.github.com/oelbaga/5019647715e68815c602ff05cff2416e#file-04-github-actions-for-auto-deployment-deploy-yml
# 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
on:
push:
branches:
- branch_name # Change to your specific branch
# - deployprod # Additional branch for deployment
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Check Node.js version
run: node -v
- name: Set up SSH
uses: webfactory/ssh-agent@v0.5.1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Deploy to DigitalOcean
env:
HOST: XX.XX.XX.XX
USERNAME: root
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
cd $TARGET_DIR
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
else
echo "Starting application: $APP_NAME"
pm2 start npm --name $APP_NAME -- start -- --port=$PORT
fi
pm2 save
EOF
@Ocelloid
Copy link

Awesome, very useful and spelled out nicely

@fernandovch
Copy link

Hi @oelbaga,
I just to want to shared my experience, maybe some other dev will have the same issues. I follow your video and guide, and for the most part I had no issues, but I was not able to access the mydomain form my local machine, I used my browser and I notice that it was getting a time out.
And from the ubuntu VM I curl to https://www.mydomain and same thing.

I fixed my issue by adding on my local host file
127.0.0.1 www.mydomain.com
127.0.0.1 mydomain.com
And on Azure, I added a new inbound rule to allow TCP port 443.

I'm kind of new using ubuntu and setting up domains on azure, so for me it was kind of tricky to fix.

@msaebi031
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