skip to content
Sumit Kumar

Deploying a Next.js/React/Express Application

/ 3 min read

This script is written for an Ubuntu EC2 instance.

1. System Update and Nginx Installation

Terminal window
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nginx

2. Install Node.js via NVM

Terminal window
curl -o- [https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh](https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh) | bash
source ~/.bashrc
nvm install 20.15.1
nvm use 20.15.1

3. Generate SSH Key

Terminal window
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa -N ""
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub

Add this public SSH key to your GitHub account settings.

4. Clone and Setup Project

Terminal window
git clone <repo-url> ~
cd <project-folder-name>
npm i
npm run build
cd ~

5. Configure Nginx for Reverse Proxy

Create a new Nginx configuration file. Replace {folder_name} with your project’s name for clarity.

Terminal window
sudo nano /etc/nginx/sites-available/{folder_name}

Add the following server block configuration. This proxies requests from port 80 to your application running on port 3000.

server {
listen 80;
server_name your_domain_name_or_public_ipv4;
location / {
proxy_pass [http://127.0.0.1:3000](http://127.0.0.1:3000);
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;
}
}

Enable the configuration by creating a symbolic link, test the syntax, and restart Nginx.

Terminal window
sudo ln -s /etc/nginx/sites-available/{folder_name} /etc/nginx/sites-enabled
sudo nginx -t
sudo service nginx restart

6. Process Management with PM2

Install PM2 globally and start your application.

Terminal window
npm i -g pm2
pm2 start npm --name "my-app" -- start

Note: Before this step, ensure your domain’s DNS records (e.g., in AWS Route 53) point to your EC2 instance’s public IPv4 address.

7. Setup HTTPS with Certbot

Install Certbot to secure your site with a free SSL certificate from Let’s Encrypt.

Terminal window
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your_domain_name

PM2 Commands for Different Frameworks

FrameworkPM2 Command
Vite Projectpm2 start npm --name "vite-app" -- run preview
Next.js Serverpm2 start npm --name "next-app" -- start
Create React Apppm2 start "serve -s build -l 3000" --name react-app
Express.js Serverpm2 start server.js --name "express-api"

Redeploying After Code Changes

Follow these steps to update your application on the EC2 instance after pushing new code to your repository.

1. Pull the Latest Code

Navigate to your project directory, pull the latest changes, and rebuild.

Terminal window
cd <project-folder-name>
git pull
npm i
npm run build

2. Restart the Application Using PM2

List all running processes to find the name or ID of your application.

Terminal window
pm2 list

Restart the specific process to apply changes with zero downtime.

Terminal window
pm2 restart <app_name_or_id>

Verify that your app is running correctly.

Terminal window
pm2 list

If the process shows an error status, check the logs for issues with the new build.

Terminal window
pm2 logs <app_name_or_id>

Nginx Configuration for a Static PHP Site

If hosting a simple PHP project, your Nginx configuration might look like this:

server {
listen 80;
server_name your_domain_name_or_public_ip;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Path may vary
}
}

Useful References