When I first started with NodeJS there were tons of resources to deploy NodeJs with on Digital Ocean droplet with managed database solutions.
However, I found a gap in resources when it came to hosting both the database and the Node.Js application on the same droplet.
I could have moved ahead with a managed database solution but I didn't want to pay just for the POC:)
Although there is Digital Ocean documentation for hosting PostgreSQL, it didn't work for my needs, possibly due to outdated information.
Let's dive straight into the topic.
This guide could serve as a reference therefore a table of contents is necessary.
- Creating a DigitalOcean Droplet
- Deploying Node.js
- Deploying PostgreSQL
- Verifying the Database Connection from Ubuntu Root Folder(optional)
- Verifying PostgreSQL Connection with Node.js
- NGINX
Creating a DigitalOcean Droplet
The first step is to create your account on DigitalOcean.
After signing up or logging in, you will be directed to the droplets page on DigitalOcean.
Here, you can create a new droplet by clicking the 'Create' button, as illustrated in the image below.
Next, select your preferred region and data center as shown in the image below.
Choose the OS image as 'Ubuntu' as we are using the Ubuntu server throughout this article as depicted in the image below.
Choose 'Password' as the authentication method as it helps you start quickly as depicted in the image below.
Select the Droplet type and CPU options as regular as depicted in the image below.
In the final step, set the hostname for your droplet as depicted in the image below.
Finally. click on the 'Create Droplet' button. Voila!, your droplet is ready.
Deploying Node.js
Log in to your droplet using SSH with the below command.
ssh root@your_droplet_ip
The above command initiates a secure connection to your Ubuntu server.
Once you have logged in, it's good practice to update your system's package index. Enter the command below
sudo apt update && sudo apt upgrade
The sudo apt update
command refreshes the list of available packages and their versions, but it doesn't install or upgrade any packages.
The sudo apt upgrade
command is used to install the newest versions of all packages currently installed on the system.
The next step is to install Node.js and npm(Node Package Manager) on your Ubuntu server
sudo apt install nodejs && sudo apt install npm
the above command installs Node.js, the JavaScript runtime, and npm, which is used to manage Node.js packages.
Next, clone your GitHub repository by using the command below.
git clone <<YOUR_GITHUB_REPO_LINK>>
Replace <<YOUR_GITHUB_REPO_LINK>>
with the actual link to your GitHub repository.
After cloning, navigate to your project repository by
cd into <<YOUR_PROJECT_NAME>>
Replace <<YOUR_PROJECT_NAME>>
with the name of your project directory.
Now, install your project dependencies.
npm install
Next, install the production process manager for Node.js applications, using the command below
npm install pm2 -g
PM2 helps in managing and keeping your application online. I'll explain more about the importance of the PM2 package shortly.
As we are talking about the TypeScript. We need to compile the TypeScript code into JavaScript. Hence we need to run the command below.
npm run build
This process sets up the Node.js server to the DigitalOcean droplet.
Deploying PostgreSQL
Now, let's deploy PostgreSQL on the same droplet.
First, install postgresql
and postgresql-contrib
by the command below.
sudo apt install postgresql postgresql-contrib
postgresql-contrib
package includes additional utilities and functionality that are not part of the standard PostgreSQL distribution. You can check here for more info.
Next, switch from the current user context to the postgres
context by running the command below.
sudo -i -u postgres
Note: -i
flag is very important without it certain environment variables, including those set in the login shell's startup scripts will not be reset or executed. In short, we can't create new users or a new database.
P.S. I invested a lot of time at the start without adding -i
flag.
Once you execute the above command you will see like below.
postgres@<<YOUR_SSHNAME>>:~$
Now, connect to the PostgreSQL command line interface(CLI) by running the command below.
psql
Upon successful connection, you'll be presented with the PostgreSQL CLI, as shown in the accompanying image.
Caution: When setting up your PostgreSQL database, it's crucial to ensure consistency between your local environment and production settings. Specifically, the database name and password you use while creating your PostgreSQL database on the DigitalOcean droplet should match those specified in your Node.js application's configuration files. This alignment is essential for successful database connection and operation, both in development and production environments.
If there's a mismatch in these credentials, your Node.js application might encounter connection issues, leading to potential downtime or functionality problems. Always double-check these details to ensure a smooth deployment process.
Next, we need to create the user role in the database. Execute the following command, replacing <<USERNAME_YOU_LIKE>>
with your desired username and <<PASSWORD_YOU_LIKE>>
with a secure password
CREATE USER <<USERNAME_YOU_LIKE>> WITH PASSWORD '<<PASSWORD_YOU_LIKE>>';
Note: It's crucial to enclose the password within single quotes ' '
After setting up the user, the next step is to create a database. Use this command, replacing <> with your chosen database name and <> with the username you created in the previous step.
CREATE DATABASE <<DATABASE_NAME>> OWNER '<<USERNAME>>';
Note: Ensure that <<USERNAME>>
matches the username you've just created.
To verify your database has been created successfully, run the command below.
\l
You should be able to see your new database on the list.
To quit the PostgreSQL command line interface. run the command below.
\q
Then, to leave the Postgres user context and return to the Ubuntu root folder, type
exit
And there you have it! We've successfully set up a user and a database in PostgreSQL on our Ubuntu server.
Uff.. It's been quite a journey, but we're making great progress.
Verifying the Database Connection from Ubuntu Root Folder(optional)
Now let's verify if we can connect to the newly created database from the Ubuntu server.
sudo adduser <<USERNAME>>
Note: This command will prompt you to create a new password for the system user and fill in some additional details. You can opt to keep these details at their default values.
To open the PostgreSQL shell as the <<USERNAME>>
, run the below command.
sudo -u <<USERNAME>> psql -d <<DATABASE_NAME>>
Once logged in, check the connection details with
\conninfo
If everything is set up correctly, you will see a message similar to:
You are connected to database <<DATABASE_NAME>> as user <<USERNAME>> via socket in "/var/run/postgresql" at port "5432".
This confirmation indicates a successful connection to your PostgreSQL database from the Ubuntu server.
Verifying PostgreSQL Connection with Node.js ###
Now we'll verify the database that we set up is successfully connected to the Node.js server.
Navigate to your project repository by
cd into <<YOUR_PROJECT_NAME>>
Once in your project directory, start your Node.js application to check the database connection
npm start
If the database connection is properly configured in your application, you should not encounter any error messages related to the database. Successful execution without errors indicates that your Node.js server is correctly connected to your PostgreSQL database.
Now, exit the project by pressing ctrl+c
and navigate to Ubuntu root server by running the command below.
cd
NGINX
Now we have come to the last bit, exposing the project to the internet.
We will use the internet's favorite(also my personal favorite) NGINX
You could ask me why NGINX.
Here are my top 3 reasons.
- Nginx efficiently handles static files and a large number of simultaneous connections, offloading this work from Node.js.
- Nginx acts as a security layer, shielding your Node.js application from direct exposure to the internet.
- Nginx can manage SSL/TLS encryption, simplifying the setup of HTTPS for your Node.js app.
With that said let's start.
Install NGINX by running the command below.
sudo apt install nginx
Next, we'll create a configuration file for your project in the /etc/nginx/sites-available/ directory. This file is crucial for directing internet traffic to your Node.js application
sudo nano /etc/nginx/sites-available/<<YOUR_PROJECT_NAME>>
You will see the empty editor like the image below.
Now let us add the below code.
server {
listen 80;
server_name <<your_domain_or_IP>>;
location / {
proxy_pass http://localhost:YOUR_NODE_JS_PORT;
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;
}
}
Replace <> with your domain name or IP address and YOUR_NODE_JS_PORT with the port number where your Node.js app is running.
This configuration does the following
- Listens on port 80, the default port for HTTP.
-
server_name
specifies the domain name or IP address NGINX responds to. -
proxy_pass
directs requests to your Node.js app. - Additional
proxy_set_header
settings ensure proper handling of connections and upgrades (important for WebSocket support).
After adding the code save the file by pressing Ctrl+O
, then press Enter
, and exit the editor with Ctrl+X
.
Next test the NGINX configuration.
sudo nginx -t
If the test is successful, create a symbolic link to enable your site configuration
sudo ln -s /etc/nginx/sites-available/<<YOUR_PROJECT_NAME>>
/etc/nginx/sites-enabled/
Restart the NGINX server to apply the changes
sudo systemctl restart nginx
Navigate to the project root by running the command below.
cd <<PROJECT_NAME>>
Finally, start your Node.js server permanently with PM2:
pm2 start dist/index.js
PM2 not only helps keep your Node.js application running efficiently but also provides a suite of features beneficial for application monitoring, logging, and performance optimization, especially in a production environment.
If you're interested in further streamlining your workflow, I have good news for you! In my next post, I delve into the intricacies of fully automating this deployment process. Check out my upcoming post
Finally
As you embark on this journey of deploying your Node.js application with PostgreSQL on DigitalOcean and configuring NGINX, feel free to use my project as a practical example to follow along with the steps outlined above.
Should you encounter any challenges or have questions during the process, please don't hesitate to leave a comment below.
Feel free to reach out to me on
Top comments (0)