How to Deploy Nextjs on AWS-EC2 (Nginx, Ubuntu, SSL)

Many developers out there could be asking themselves the steps to successfully deploy a Nextjs application in AWS. While Vercel is a known cloud platform, praised for its user-friendly interface and straightforward deployment process, AWS is a comprehensive cloud service provider that offers a wide range of services. It’s true that you could deploy easier your app in Vercel, still, if you are reading this article is because we may share similar perspectives about organization.

Next.js is a web development framework that excels in delivering high-performance web applications. Its key features, including Server-Side Rendering (SSR) and Static Site Generation (SSG), boost your site's speed and SEO ranking. With Next.js, you can reap the benefits of server-generated HTML, leading to faster load times and an SEO-friendly architecture.

Once you have setup a secured connection to your EC2 instance, then follow the steps listed below.

Step 1: This should be your initial screen before heading forward.
Step 2: Update

Run the following command to update all system packages.

sudo apt-get update

Download and import the Nodesource GPG key

sudo apt-get install -y ca-certificates curl gnupg

sudo mkdir -p /etc/apt/keyrings

curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

Step 3: Create a deb repository and install any supported Nodejs version

NODE_MAJOR=21

// set the Node version to install

echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

// create a deb repository

The Nodejs version is set by running "NODE_MAJOR= #version" - where #version can be 16, 18, 20, 21, etc

Let's set Nodejs version to 21 - NODE_MAJOR=21

sudo apt-get update

// update your system variables

sudo apt-get install nodejs -y

// install Nodejs using the version stated previously

To Uninstall Nodejs you can run the following command

sudo apt-get purge nodejs &&\rm -r /etc/apt/sources.list.d/nodesource.list &&\rm -r /etc/apt/keyrings/nodesource.gpg

// uninstall nodejs entirely

Verify the nodejs version you just installed

Step 4: Create an SSH Key Pair

We need to create an SSH key pair to setup a secured communication with your GitHub repository.

Use the following procedure to generate an SSH key pair on UNIX and UNIX-like systems:

1. Run the ssh-keygen command. You can use the -t option to specify the type of key to create. For example, to create an RSA key, run: ssh-keygen -t rsa

2. You can use the -b option to specify the length (bit size) of the key, as shown in the following example: ssh-keygen -b 2048 -t rsa

ssh-keygen -b 2048 -t rsa

// create your ssh key using this command

Step 5: Copy the value of this public SSH key

Since by default you are located at "./Home" directory, you would only need to access the "./.ssh" directory in order to gather the public key.

cd .ssh

// Enter .ssh directory

ls

// List all files inside this directory

cat id_rsa.pub

// open the file id_rsa.pub and copy its content

Step 6: Open your GitHub repository

Access its "Settings"

Scroll down the side left menu until you find "Deploy keys"

Press the button "Add deploy key"

Then, input a name for this key and enter the value you copied in the text area, under "Key".

There is no need to "Allow write access" since you would be only reading from your remote EC2 Instance.

Step 7: Copy the SSH command linked to your repository
Step 8: Now get back to your Putty session

Write the following command to clone your GitHub repository

git clone "your GitHub copied command"

// Enter .ssh directory

Step 9: Install all dependencies

ls

// List all directories inside

cd "your directory name"

// Access your application main directory

npm i

// Install all dependencies

Step 10: Generate an optimized version of your application for production.

npm run build

npm install sharp

// for nextjs to use automatically over Image optimization

Step 11: Install PM2

We require a solution for handling the Next.js process, ensuring it continues running in the background even after closing the terminal. To fulfill this need, PM2 serves as the ideal tool for managing the process.

• Install PM2 using the below command:

sudo npm install pm2 -g

Step 12: Run Next.js via PM2 in the background

We need to run, stop and restart the Next.js application even after the terminal is closed. This can be achieved using the PM2 tool.

Execute the below code to run Next.js with PM2:

pm2 start npm --name nextjs-app -- run start -- -p 3000

We can also check the status of our nextjs-app by using the below command:

pm2 list nextjs-app

Step 13: Setup a Firewall

sudo ufw enable

// enable Firewall

sudo ufw status

// See firewall status

sudo ufw allow ssh

// Port 22

sudo ufw allow http

// Port 80

sudo ufw allow https

// Port 443

Step 14: Install Nginx

sudo apt install nginx

Step 15: Configure Nginx

Its main function in this deployment is a Reverse Proxy with Caching

Use the command below to modify its default file

sudo nano /etc/nginx/sites-available/default

Once you are inside the file, locate the "server_name" and "location /" part to replace it with the text provided below

server_name yourdomain.com www.yourdomain.com;

location / {

proxy_pass http://localhost:5000; #whatever port your app runs on

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;

}

Now, test the configuration you just changed.

sudo nginx -t

// Test the configuration for Nginx default

sudo service nginx restart

// Restart Nginx to load the new configurations

Step 16: Connect the Domain where you want to deploy this app, to this EC2 Instance

Copy the Public IP address indentifying this EC2 instance

Paste it in the main record "Type A" if you had it created before. If not, feel free to "Create record"

Here if you access your domain you will notice it is not secured. (Port 80 HTTP)

Step 17: Installing Let's Encrypt cerbot

sudo apt install certbot python3-certbot-nginx

//

sudo apt-get update

// update packages

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

// Request SSL/TLS certificates

If you refresh now your browser, you will notice that traffic is secured now.