Deploying a Next.js application to DigitalOcean with a Custom Domain and SSL Certificate

Ronaldo B.September 2, 202213 min read

In this article

In this article we will learn how to deploy a Next.js application using TypeScript on DigitalOcean, defining a custom domain and SSL certificate through the insurer Let’s Encrypt.

The project will be adapted from the opening of Star Wars in HTML5 and CSS3, which we taught how to create in this article: Recreating the opening of Star Wars with CSS3 and Sass. This article will be divided among the following topics:

  1. Adapting Project for Next.js
  2. Creating Droplet on DigitalOcean
  3. Deploying on the Server
  4. Defining Proxy with Nginx
  5. Adding Custom Domain
  6. Configuring SSL Certificate

Adapting Project for Next.js

To create our project using Next.js, we will use the npx feature.

npx create-nuxt-app star-wars-next

After creating the project, we will start it. To do this, let's access the project and then execute the npm script to start our development server:

cd star-wars-next
npm run dev

With these commands executed, we will see the screen below, indicating that the server has started:

Development server with Next

Adding TypeScript to the project

Our project will have TypeScript in its structure. The first thing we need to do is create a file tsconfig.json, used by TypeScript to define its configurations.

After that, it is necessary to add TypeScript to our project via npm, as well as the necessary types for React, used by Next.js, and also for Node.js:

npm install -D typescript @types/react @types/node

After that, we can start the development server again:

npm run dev

With this command, the tsconfig.json file will be automatically filled with its default configurations:

tsconfig.json file filled with project information

With this, TypeScript will be completely added and configured in our project.

Adding Sass

An essential part of our project is the use of Sass, responsible for helping us develop CSS code more easily and with advanced features. This resource will be added as a development dependency:

npm install -D sass

After installing Sass, we need to add some configurations so that this dependency works correctly.

For this, we need to edit the next.config.js file and add the following configurations:

const path = require('path');

module.exports = {
    sassOptions: {
        includePath: [path.join(__dirname, 'styles')]
    }
}

Adapting Project for Next.js

To adapt our project already created with HTML5, CSS3, and Sass, we will need to edit the index.tsx file in the pages directory and also the Home.module.scss file:

index.tsx file

Besides the .tsx file, we also need to edit the .scss file:

Home.module.scss file

With this, we will see our project already working using Next.js.

Creating Droplet on DigitalOcean

It is necessary to have an account created on DigitalOcean to be able to create a new project, or Droplet, on this cloud server provider.

After creating a new project, we will click on “Create > Droplets”:

Option to create a new droplet

On the creation page, we will first select the image of our operating system. We will choose Ubuntu 20.04:

Selecting Ubuntu Operating System

Next, we will select the plan for our project. We will choose the most basic plan:

Selecting the plan for our project

We will also choose the region where our server will be located:

Region of our server hosted on DigitalOcean

Next, we need to select the method of authentication for accessing our server. We will select SSH keys. For that, we will need to create a new SSH key.

Creating SSH Key

To create an SSH key we will use the PuttyGen program. We can download it using the following link: https://www.putty.org/.

After downloading the program, we will open it and click the “Generate” button:

Button to generate new key

Next, you need to move your mouse over a blank area at random. This pattern will be used to create a unique SSH key:

Creating unique SSH key

After a few seconds, the following window will appear:

Window for SSH key creation

Note that there are two fields to add a password for our SSH key. This is interesting to increase security in the use of keys. Therefore, if you wish to add this password, it would be very good.

With the key created, we need to save it in a file. Two files will be created: 1) the public key, which will be added to DigitalOcean, and 2) the private key, which will be used to confirm that the specific key refers to our personal machine.

We will click on the “Save public key” and “Save private key” options:

Options to save keys

We can identify our keys with any name we like:

Public and private files of our SSH key

Do not close the PuttyGen window yet, as we will still use it.

Let’s go back to the DigitalOcean site and click the option to add a new SSH key:

Option to add a new SSH key on DigitalOcean

We will need to go back to the PuttyGen screen one more time and now we will copy the key that is in the “Key” field. Just select it, right-click and click “Copy”:

Copying SSH key from PuttyGen

We will paste its content into DigitalOcean, define a name for our key, and then click on “Add SSH Key”:

Adding SSH key to DigitalOcean

Next, we can select only one droplet in the finalization section and name our server. In our case, we will define the name as “STARSERVER”:

Defining a name for our server

Finally, we can click on “Create Droplet” to actually create our server:

Option to finalize the creation of our Droplet

With this, the creation of our server on DigitalOcean will be completed.

Deploying on the Server

The next step of our article will be to access our remote server to deploy our application in the cloud. For that, we will use Putty again.

The first thing we need to know is the IP of our server. We can find this in the DigitalOcean admin panel. The server's IP is shown next to its name:

IP of our server

When accessing the Putty program, we can add our server's IP, the port that will be used to connect to the server, in our case, it will be port 22, the type of connection, which by default is SSH, and the name of the server, so we can access it more easily in future sessions. We can define it as “STARSERVER”:

Configuring our server on Putty

The next configuration we need to make is related to authentication. In the left menu of Putty, we will click on “Connection > SSH > Auth”:

Putty authentication configuration

We will click the “Browse...” button so that we can select the file that contains our private SSH key:

Selecting private key

When clicking this option, a Windows Explorer window will open. Select your private key and click “Open.” It should have the “.ppk” extension:

Selecting private key

It is important to keep these files in a safe place on your computer. If you need to access the server from another location, you will need to make a copy of the SSH key files, or generate a new key in that other location.

We can go back to the “Session” tab, click “Save” so that this session is saved in our program, and then click “Open” to actually access our server:

Accessing the server

The first time we access the server, we will encounter the following message. Just click “Yes”:

Warning message

The first credential requested will be the login. We can enter “root,” which is the default login for DigitalOcean:

Login to our server

Next, we will be prompted for the password of our SSH key. If we have set one, just enter it at this time:

Entering password for our SSH key

With this, we will be logged into our remote server. We are ready to clone our project.

For this, we will use Git, which is widely used for version control of various projects. The Ubuntu servers on DigitalOcean already have Git installed by default.

Let's access the var directory:

cd /var

We will clone our project in this directory:

git clone https://github.com/hcodebr/star-wars-next.git

Since we are running a Node project, we could choose any other directory, but we prefer the var directory.

Installing Node

We now need to install Node.js on our server. To do this, we will first update our apt toolset:

sudo apt update

Next, we will download the Node setup directly from the nodesource domain. We will use the following command for that:

curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh

Note that we selected setup_14.x. This will download version 14 of Node. But we could choose another version if we wanted.

After the download is finished, we will check if the nodesource_setup.sh file was downloaded correctly. We can use the following command for that:

sudo nano nodesource_setup.sh

If any content is presented for this file, we know it was downloaded correctly. We can then execute it through this other command:

sudo bash nodesource_setup.sh

After that, we can use apt to install Node:

sudo apt install nodejs -y

After installation, we can check the version of Node installed on our server with the command node --version:

Node version installed

Installing dependencies

Next, we can install the dependencies of our project. Let's access the directory of our project:

cd /var/star-wars-next

To install these dependencies, we can use the command npm install.

The next step is to prepare our files for production. For that, we can use the command npm run build.

Finally, we can indeed start our project, using the command npm start.

Now, if we access the URL http://167.71.110.237 on port 3000, which is used by Next.js, we will already be able to see our project working:

Project running on port 3000

This is excellent. However, if we end our Putty session, our Terminal that is running the project will be terminated. It is necessary to define that the project continues running 24 hours a day, without us having to access our server every time. To help us with this issue, we can use a process manager called pm2.

Installing and Configuring pm2

To install pm2, we can use the following command:

npm install pm2 -g

In this way, pm2 will be installed globally on our server.

To start it, you need to give a name to our application. In our case, we will name it “next” for our project. We will use the following command:

 pm2 start npm --name next -- start

After starting our project, we will see the following table:

Project table with pm2

It shows how many projects are online and some very interesting statistics, such as how much memory has already been used by it.

To save this configuration, we can use the command pm2 save.

This way, even if we close the access window to the server, our project will remain online.

Proxy with Nginx

Our project is already running, but we need to explicitly inform that we want to access the server's port 3000. However, this is not interesting for most users. We just want to inform the server IP and be redirected to our project.

The default port for accessing Web servers is 80. Thus, it will be necessary to create a proxy, which will be an intermediary server responsible for directing our users to the actual port of our project, that is, port 3000.

It is necessary that we use an HTTP server for this. It will listen by default on port 80. We will use Nginx in our case. Let's install it using the command below:

sudo apt install nginx -y

After its installation, let’s access the directory that contains the registered sites on this server:

cd /etc/nginx/sites-available

We will access the configuration of the default server:

sudo nano default

In this file, we will find the location directive. We will define its structure as follows:

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;
}

Configuring our proxy with Nginx

With this code, we are defining that Nginx will receive requests on port 80 but will direct them to localhost:3000, that is, to our project.

After making these configurations, we can restart our Nginx server:

sudo service nginx restart

With that, our project will already be running through port 80, without us having to inform :3000.

Adding Custom Domain

Our server is getting better and better. However, there are some features that we can improve even more. For example, we still don’t have a custom domain (DNS) for our project. This is the next issue we will configure.

To configure a DNS server, we first need a domain registered in our name. The site registro.br is widely used for the registration of “.br” domains at an annual price of R$ 40.

We will use the domain myapp.dev.br in our project. To set it up, we can return to our server and make a copy of the default Nginx file. By convention, we will name this new file with the name of our server followed by the suffix “.conf.”:

sudo cp default myapp.dev.br.conf

We will access this new file and look for the server_name directive. We will define the name of our server as its content:

server_name myapp.dev.br www.myapp.dev.br;

Note that we defined the name of our server both without and with the prefix “www.”

With this configuration, our domain is already available on our server, but it is still not enabled. For that to occur, we need to make a copy of this file to the sites-enabled directory. To avoid a duplicate file, we can create a link from the file in the sites-available directory to the sites-enabled directory. A link in Linux is like a shortcut that we know in Windows. To create it, we will use the following command:

sudo ln -s myapp.dev.br.conf /etc/nginx/sites-enabled/

This is the necessary configuration on our server. What we need now is to add the domain registered on DigitalOcean. For that, we will return to our server panel, click the three dots that show more options and then select “Add a domain”:

Option to add a domain on DigitalOcean

On the next page, we will provide our domain and select the project to which it will be directed. After that, we can click on “Add Domain”:

Adding domain to our project on DigitalOcean

On the next page, we will add new records for our domain. We will add an “A” type record, setting the hostname to “@” and selecting our project “STAR-SERVER” as the redirect. Then we can click on “Create Record.”:

Adding A type record

We will repeat the same process, but informing “www” as the hostname:

Adding www as hostname

These new configurations will introduce a series of new DNS records. But we will focus on three specific ones:

DNS records in our project

We will copy these three DNS records and add them to our domain on the registro.br site. We will click to edit our domain and in the DNS area, we will add these records:

Adding DNS records on registro.br

Thus, when accessing http://myapp.dev.br, we will see our project already working with a custom domain.

Configuring SSL Certificate

After adding a custom domain to our project, what we need to do now is to define an SSL certificate so that our server is regarded as secure.

We will use the Let’s Encrypt project, which provides free SSL certificates that need to be renewed every three months. The website of this project suggests using the software Certbot.

We will install it on our server with the following command:

sudo apt install certbot python3-certbot-nginx -y

Note that we also installed a package called python3-certbot-nginx. It is the plugin that performs SSL certificate configuration on Nginx servers.

To create our certificate, we can call certbot along with some flags:

sudo certbot --nginx -d myapp.dev.br -d www.myapp.dev.br

The first thing we need to inform is the email associated with our server. We can provide a personal or company email:

Informing the email related to the SSL certificate

Next, we need to confirm that we accept the terms of service of Certbot. We can press “A” to accept and “C” to cancel the process:

Accepting the terms of Certbot

The next question asks us if we allow our email to be shared with Let’s Encrypt partners. We can respond “Y” for yes and “N” for no:

Allowing or not sharing the email address with Let’s Encrypt partners

Through the last question, we can define whether we want to redirect URLs with HTTP to HTTPS. We can type “2” for this redirection to occur:

Defining redirection to the HTTPS server

After this, our certificate will be created and a success message will be returned:

Success message in creating our SSL certificate

Now, if we access our project with HTTPS, we will see the lock icon in the URL and also a message indicating that our connection is secure:

Lock icon in our secure connection

Our Next.js project is fully added to our server on DigitalOcean.

Conclusion

In this article, we learned how to fully deploy a Next.js project to DigitalOcean.

We hope this content can help you to also deploy your applications to the cloud, a skill that is so necessary for programmers today.

Don't forget to share this article if you liked the content. See you in the next article. :)

Keep learning with Hcode

Sign up for the course platform and follow the next blog guides.