post image

Deploy Next.JS Application on AWS Lightsail

This tutorial discusses how to deploy your Next.JS app over AWS Lightsail. Lightsail brings a simple user interface to configure various services in order to build a site — servers, cdn, domain etc.

The tutorial covers creating an instance (virtual server), moving the application's code to it and configure network operations.

Domains are then discussed on how to assign your domain to the running Next.JS app.

Finally CDN distributions are also covered on how the built HTML pages from the Next.JS app can be cached over a CDN.

Btw, usefulangle.com is also a Next.JS application deployed on AWS Lightsail.

Creating an Instance

The first step would be obviously to create a virtual server infrastructure on which our Next.JS app will execute.

  • Go to Instances and create an instance
  • Select Ubuntu 22 as the operating system (we're going to install Node.JS later).

  • Choose your instance plan
  • Give a name to your instance
  • Leave other settings as it is (if you don't understand what they mean)
  • Create the instance

Add Network Settings for the Instance

The instance that was created will have an IP address. However this IP may change if you stop or restart your instance.

A static IP address is needed for the instance to configure the CDN (will come later).

You also need to configure the instance to allow the port on which our Next.JS app is running.

  • Go the instance that was created. Click on the Networking tab.
  • Attach a static IP to the instance.
  • Also add a rule to the IPv4 Firewall. Include the port over which your Next.JS app is going to run. The below screenshot is assuming you're running your Next.JS app on port 3000.

    Addition of this rule is mostly for checking, and can be removed once the Next.JS app starts accepting requests on port 80 via a proxy server.

Connect to Instance

Now you need to connect to the instance and start installing required applications and libraries.

Go to the instance, and click on the Connect tab. You can use your own SSH client to connect to instance, however there is also a functionality to connect to the instance via the browser. This is much easier, and works in the same way.

You may also need to create a SSH key for the region, if you haven't created it before.

Once you have connected to the instance, first step is to obviously update the Ubuntu repositories.

sudo apt-get update

Installing Node.js

First you need to install Node.js in the instance. The below commands will install the latest LTS version of Node.js (18.x at this time). You can install your own Node.js version by updating the curl url.

  • curl -fsSL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh
  • sudo -E bash nodesource_setup.sh
  • sudo apt-get install -y nodejs
  • Verify the installation

    node -v

Install PM2 to Keep Running Next.JS App Indefinitely

Once the Next.JS app is installed, it needs to keep running indefinitely (otherwise the app will stop running as soon as the terminal gets closed). A process manager is needed for this. PM2 is the most popular process manager application.

Install PM2 globally.

sudo npm install -g pm2

Move Application Code to Instance and Install Next.JS App

You now need to move your Next.JS code to the instance and install the app.

The preferred way is obviously doing it with git.

  • Git clone the app

    git clone https://clone-url/yourrepo
  • cd into the cloned directory

    cd yourrepo
  • Install the Next.JS app

    npm install
  • Build the app

    npm run build
  • Start the server with PM2

    pm2 start npm --name "app-name" -- start

The Next.JS app is now installed on the instance. You can visit this in the browser using the IP address of the instance and the port on which the app is running.

In case you need to stop the app and re-build it, you can use these PM2 commands :

# stop process
pm2 stop app-name

# restart process after build
pm2 restart app-name

Installing Nginx as Proxy to the Next.JS App

The installed Next.JS app is running on a specific port (3000 for example). By default Next.JS has made it difficult to run the app on port 80 — that is a security concern and understandable.

You need to install Nginx and configure it as a proxy to your Next.JS application server.

Configuring Nginx as a proxy is a delicate thing. Make sure you're doing it correctly.

  • Install Nginx

    sudo apt-get install -y nginx
  • Edit Nginx config file at /etc/nginx/sites-available/default (since the role of Nginx in this intance is only to act as a proxy, the simplest thing to do is to change the default config).

    sudo nano /etc/nginx/sites-available/default
  • Replace the config file with the following. Change port 3000 to the port on which your Next.JS app is running.

    server {
    	listen 80;
    	location / {
    		proxy_pass http://localhost: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;
  • Check whether the Nginx's configuration is correct. You should be getting a successful message.

    sudo nginx -t
  • Restart Nginx.

    sudo systemctl restart nginx

The Next.JS app can now be accessed without including the port number. You can visit by just using the IP address of the instance.

Now that the Next.JS can be accessed over http (port 80), we can remove the port number of the Next.JS application from the instance's IPv4 Firewall. This will ensure others cannot access the application at that port number.

At this point your Next.JS app is deployed and accessible over http. The next sections will briefly describe about assigning your domain and/or connecting the app to a CDN.

Adding Domain

You can go the Domains and DNS section and add your domain.

If the domain belongs to another hosting provider, you will need to create a DNS zone for it and allow the domain's DNS to be controlled by AWS nameservers.

If the domain is registered directly on AWS, then process is a bit easier.

The end result of this is your domain being successfully added.

Accessing Next.JS App Over a Domain

At this point your Next.JS is deployed on the instance and can be accessible via its IP address over http. To assign the domain to the instance, you have 2 options now :

  1. Assign the domain directly to the instance.
  2. Or connect the instance to a CDN distribution, and assign the domain to the distribution. If your Next.JS app builds mostly static pages (blog for example), then CDN is a good option. It also has the additional advantage that you don't need to do anything special for enabling https on your site, as SSL certificate will be provided by AWS for free.

The next two sections will discuss both of these options.

Assign Domain to the Instance

  • You can assign your domain directly to the instance, via the Domains tab of the instance. The domain will be accessible over http.

  • To make the domain accessible over https, you will need to edit Nginx config file at /etc/nginx/sites-available/default (which was edited earlier too) and include path to the SSL certificates. You will need to get the SSL certificates first.

    server {
    	listen 443 ssl;
    	ssl_certificate /etc/nginx/ssl/server.crt;
    	ssl_certificate_key /etc/nginx/ssl/server.key;
    	location / {
    		proxy_pass http://localhost: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;

After this check whether the Nginx's configuration is correct, and restart Nginx. If all good, you can access the Next.JS app over your domain.

Connect Instance to a CDN Distribution and Assign Domain to Distribution

You will need to create a CDN distribution and SSL certificate, then attach those to the domain.

  • Go to the Networking section and create a distribution.
  • Choose your instance as your origin. The distribution will connect to your instance via HTTP.

  • Under caching behavior, specify your settings. However one thing you should make sure is that the CDN should forward default headers.

  • Create the distribution.
  • After the distribution is created, go the Custom domains tab. You will need to create a SSL certificate. Domain validation may be required too.

  • Finally attach the SSL certificate.

At this point you can access the Next.JS app over your domain via https.