< Back to blog
PUBLISH DATE:
Share on:
1475Set Up a Digital Ocean Server for a Node.js With PostgreSQL in 15 Minutes or LessSergey GornostaevFull-Stack Developer

Set Up a Digital Ocean Server for a Node.js With PostgreSQL in 15 Minutes or Less

Here comes a list of steps to quickly configure your Node.js application server

Each of us sometimes needs to quickly set up a server to try out an idea or quickly start development. And every time, you have to google settings and commands that you do not use so often in everyday life. Moreover, you can easily overlook an important thing, because setting up a server requires an understanding of many aspects of administration and programming.

I have gone through this myself. And today, I have decided to help you out with this task. For this reason, I have compiled a list of steps and tips that will help you quickly configure your server to start with Node.js application development. Once again, I will make a reservation that this is a basic list and is intended only for the configuration with which you can start.

Getting Started

First of all, we need to make a droplet without presets on Ubuntu 20.10 and buy a domain.

You also need to have access from your local machine to this droplet by SSH. A fairly detailed section of the documentation on the Digital Oceans site will help us with this.

This completes the preparatory work. Now, let’s start setting up.

Step 1. Install Node.js using PPA

On the server, I think there is no big need to switch versions often. Therefore, we install the needed version of Node.js using a personal package archive.

1
2
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs

Step 2. Install and setup Nginx

We will use Nginx to deliver static files. It is unwise to force your application to do this, right? 🙂 Also, a little later, we will configure proxying.

1
sudo apt install nginx

We can check with the systemd init system to make sure the service is running by typing:

1
systemctl status nginx

If you see about the same as in the image above, then everything is cool, and we can continue.

Step 3. Configure the Firewall

DigitalOcean uses cloud firewalls for blocking all traffic that is not explicitly permitted by a rule. We need to add special rules for the newly installed Nginx. Otherwise, nothing will work.

1
2
3
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

It is very important to add the rules first, and only then — enable firewalls. Otherwise, your current SSH connection may be interrupted, and you will have to restore access through the console from the web interface, which is not very convenient.

We will not specifically open the port on which the database will be located. A little bit of ninja security, and you can get access through the SSH, which we already have configured.

You can verify the change by typing:

1
sudo ufw status

Step 4. Create app directory and set up Nginx server blocks

A small remark: in order to work with the domain, you need to write down the IP address of your droplet in the domain DNS. After some time, these changes will be applied and your domain will redirect to your server.

Create a folder for your project in /var/www

1
2
sudo mkdir -p /var/www/appname.com
touch /var/www/appname.com/index.html // create blank index page

This is due to the fact that, for some other directories, we will have problems with access rights, and we do not want to solve them now. Therefore, we leave the default value and move on.

Create a new server block configuration:

1
vim /etc/nginx/sites-available/appname.com

This is a sample of settings just to see if everything works:

1
2
3
4
5
6
7
8
9
10
server {
    listen 80 default_server;
	listen [::]:80 default_server;
	server_name appname.com
	index index.html;
	root  /var/www/appname.com;
	location / {
   	 try_files $uri $uri/ =404;
	}
}

Then create a symlink from sites-available directory to sites-enabled directory:

1
ln -s /etc/nginx/sites-available/appname.com /etc/nginx/sites-enabled/appname.com

We need to get rid of the default settings and for this we will apply a little ninja tactics:

1
2
3
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup
rm -rf /etc/nginx/sites-available/default
touch /etc/nginx/sites-available/default

Next, test to make sure that there are no syntax errors in any of your Nginx files:

1
sudo nginx -t

If no problems were found, restart Nginx to enable your changes:

1
sudo systemctl restart nginx

Right now, we can make sure everything is working by simply typing the IP address of your server. Excellent. Moving right along.

Step 5. Add SSL certificate using Let’s Encrypt

Install Certbot and its Nginx plugin with apt:

1
sudo apt install certbot python3-certbot-nginx // for Ubuntu 20.10

Obtain an SSL Certificate:

1
sudo certbot --nginx -d appname.com -d www.appname.com

Then, we just follow the instructions and provide the information that is needed for the certificate. Certbot will correct the Nginx configuration for us so that everything works through https. Nothing complicated.

And the last thing we need to do is verifying Certbot auto-renewal:

1
2
sudo systemctl status certbot.timer
sudo certbot renew --dry-run

Step 6. Install PostgreSQL

Run the following command to install PostgreSQL:

1
sudo apt install postgresql postgresql-contrib

We can play with the database settings for our specific server configuration. For this purpose, you can use the online tool named PGTune.

Step 7. Create user, database, grant privileges/access

Switch to postgres user and enter the Postgres terminal:

1
sudo -u postgres psql

Create a database and a user:

1
2
CREATE DATABASE appname;
CREATE USER appuser WITH PASSWORD 'password';

Grant privileges on the database to the user:

1
GRANT ALL PRIVILEGES ON DATABASE "appname" to appuser;

Now, we will try to access the database from your computer. I am using TablePlus, and the connection setup screen looks like this:

Step 8. Install PM2 and start simple Node.js application

We need to install something that will monitor your application, restart it when the droplet reboots, and so on. PM2 is perfect for this.

1
npm install pm2@latest -g

To get the automatically-configured startup script for your machine, you need to type this command:

1
pm2 startup

First of all, we need to write your server application. It will be very simple, the main thing is to understand how it works.

Let’s create an ‘app’ folder in the root of your /var/www/appname folder from where your application will be launched. This is necessary for all your files with environment settings, pm2 setting file, etc. to be located at the root. This is how regular users of your application will not be able to reach them.

1
2
mkdir /var/www/appname.com/app
vim /var/www/appname.com/app/server.js

Now let’s write the code of the simplest application in Node.js:

1
const http = require('http');
1
2
3
4
http.createServer((request, response) => {
    response.writeHead(200, { 'Content-Type': 'text/html' });
    response.end('It works!', 'utf-8');
}).listen(3000);

Then, add the configuration file for pm2 to /var/www/appname.com. In this example, I used Javascript formatting with ecosystem.config.js name:

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
  apps: [
	{
  	    name: 'appname',
  	    script: './app/server.js',
  	    instances: 'max',
  	    exec_mode: 'cluster',
  	    env_production: {
    	    NODE_ENV: 'production',
	},
  ],
};

You can start your application via: pm2 start ecosystem.config.js –env production Let’s change your Nginx configuration a little to use proxying. We will remove the line that was in the block with the root location and replace it with the proxying settings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
location / {
     proxy_pass 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_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
}

Now all your requests will be redirected to port 3000 and the result of your script will be displayed in the browser.

To Wrap Up

This is not an ultimate list of steps, and I deliberately omitted some points to simplify the article. For example, a very important point I should have also mentioned is not to work with the server directly under the root user. But you can read other articles on how to set up secure access to the database and droplet and put this experience together to make the configuration even cooler.

And of course, it is worth remembering that progress does not stand still, and it is likely that this article will become irrelevant in some time. But I hope it does not happen very soon.

Do you need help setting up your server and starting your Node.js application?

I will be happy to help with your task. I have many years of experience with Node.js development, and I will be willing to jumpstart your application.

Alex Pletnov Sergey Gornostaev Senior full-stack JS developer

Share on: