By Kati Frantz, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
Node.js is a Javascript runtime environment used to build high-performance and fast server-side applications. Node.js server-side applications, if deployed in the wrong way could become really slow and not be able to support a growing traffic.
In this tutorial, we will cover setting up a production-ready Node.js application using the amazing services provided by Alibaba Cloud services. We'll be deploying an application called Node.js Blog, and to do this, we'll be using the following Alibaba Cloud services:
Before you begin this tutorial you'll need the following:
Note: Make sure the ECS instance and the ApsaraDB for MongoDB instance are created in exactly the same zone. This will improve application performance and also avoid any connection issues or restrictions.
In this step, we'll be installing all the dependencies we need to be able to run our node js application. To follow along, make sure you are logged in to your ECS instance.
To be able to get the application code from GitHub, we'll have to clone the repository using git. Let's install git on our instance using the following command:
sudo apt-get install git
To verify the installation, run the following command to check the version of git installed: git --version
. In my case, I receive the following output: git version 2.7.4
.
To run a node.js application, we need to install the specific node js version required for this application to run. For our node js blog, we require Node version 8 or above. To install it, run the following command:
curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
This command downloads a file called nodesource_setup.sh
which is a shell script to install node js on our instance. Run this shell script with the following command:
sudo bash nodesource_setup.sh
And finally, to complete the installation, run the following:
sudo apt-get install -y nodejs
To verify your node js installation, run node -v
to see what version of node was installed. In my case I receive the latest subversion of version 8 which is v8.13.0
.
Nginx is one of the most popular web servers in the world and is being used by some of the largest sites. To deploy our application, we'll be serving our application using nginx as a proxy server. We'll talk more about this. To install nginx, run the following:
sudo apt-get install nginx
To test your installation, run nginx -v
to see the installed version. In my case, I receive the following output: nginx version: nginx/1.10.3 (Ubuntu)
.
Node.js applications are very brittle, and in production, we need to use a powerful process manager to monitor out node js application, making sure the process is always running. The process manager we'll use in this case is called pm2
and comes as a node js package. PM2 not only monitors our node js application for crashes, but also automatically scales our node js application, optimizing all the CPUs on the instance. To install PM2, run the following:
npm i -g pm2
To verify your installation, run pm2 -v
. In my case, I receive the following output: 3.2.2
.
In this step, we'll clone the application repository so we can run on our instance.
To clone the application code, run the following command:
cd /home
git clone https://github.com/bahdcasts/node-js-blog.git
To install the project dependencies, run the following command:
cd /home/node-js-blog
npm install
Most node js applications would require setting up server environment variables. This project uses a package called dot-env
, and using this package, we can place all our environment variables in a file called .env
. We'll create this file, and add some environment variables to it. Run the following command:
cd /home/node-js-blog
nano .env
This opens a new file called .env
using the terminal code editor nano
. Place the following content into the file:
PORT=3000
DB_URI=
CLOUDINARY_API_KEY=xxxx
CLOUDINARY_API_SECRET=xxxx
CLOUDINARY_NAME=xxx
EXPRESS_SESSION_KEY=d29z4944SxETKPNWqKAkCNUjrZ4A
These are the environment variables required for this project to work. The PORT
is the specific port on which our Node js application will run on. The EXPRESS_SESSION_KEY
is just a random string used to encrypt user sessions.
Also, the images of this blog are uploaded to cloudinary, and the cloudinary environment variables are required for that. You could skip this, since it's not the focus of this tutorial. This is just to show you how to setup your own custom environment variables when deploying your own Node js projects.
The final environment variable is the DB_URI
and this will be the environment variable for connecting to our ApsaraDB for MongoDB
instance. We'll add this in a later step.
Note: To quit the nano
editor, use CTRL + X
and then Y
.
In this step, we'll connect our application to the ApsaraDB for MongoDB
instance we created earlier.
By default the MongoDB instance doesn not permit connections from any address. Using the console, we'll whitelist the IP address of our ECS instance so that our application can open a successful connection.
First, visit your console, open the MongoDB instance, and visit the Data Security
tab. Here, click on the Manually modify
button to add a new IP address.
Save the changes. This action gives the permission for our application to connect to this MongoDB instance.
From the Database Connection
tab, get the connection string to the database:
Now copy the connection string, and update the value of the DB_URI
environment variable. Using nano .env
, your .env
file should look like this:
PORT=3000
DB_URI="mongodb://root:passWORD1234@dds-gs50fb23291731d41.mongodb.singapore.rds.aliyuncs.com:3717,dds-gs50fb23291731d42.mongodb.singapore.rds.aliyuncs.com:3717/admin?replicaSet=mgset-300215248"
CLOUDINARY_API_KEY=132255634713478
CLOUDINARY_API_SECRET=aeBNzdZFcju9ZEAiL7KsEMbBlFI
CLOUDINARY_NAME=bahdcoder
EXPRESS_SESSION_KEY=d29z4944SxETKPNWqKAkCNUjrZ4P
Note: Don't forget to replace the ****
in the string with the actual root password of the instance.
In this step, we'll setup the nginx configuration, so that the nginx web server can serve our node js application.
To do this, we'll edit the default nginx configuration file. Run the following command:
# Empty the current configuration file
echo > /etc/nginx/sites-available/default
# Open the file using nano
nano /etc/nginx/sites-available/default
Replace the content of this file with the following:
server {
listen 80;
server_name 47.88.230.255;
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_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
}
The two important configuration to note are server_name
and proxy_pass
. The server_name
ideally should be your application's domain name, and it tells nginx to use the underlying configuration if a user tries to access that specific site. In this case, we simply use the ECS instance IP address since we won't be setting up a domain name for this application.
Secondly, the proxy_pass
configuration tells nginx to redirect all incoming traffic for the server_name
to the process running on http://localhost:3000
. This means whenever a user tries to access 47.88.230.255
, nginx redirects the user's request to the node js application running on port 3000
. We use 3000
in this case because that's the port on which we will be starting our node js application.
Note: Remember to replace 47.88.230.255
with the actual IP address of your own ECS instance.
Finally, we need to restart nginx so that the configuration changes are saved.
Run the following command to do so:
sudo systemctl restart nginx
Finally, we need to start our node js application using the process manager PM2. To do this, run the following command:
cd /home/node-js-blog
pm2 start index.js --name "blog"
This command starts the application using the index.js
file as root, and gives this process a name blog
. The command gives the following output:
To debug and monitor our application, we can view all messages logged from our application in real time using the following command:
pm2 logs blog
This prints out the logs for the process called blog
. The output looks something like this:
In this tutorial, we learnt how to deploy a production application using Alibaba Cloud Elastic Compute Service (ECS) and ApsaraDB for MongoDB. We also used an advanced process manager called PM2 to manage and automatically scale our Node.js application.
How to Build a Modern Web App to Manage Events with AdonisJS and React
2,599 posts | 762 followers
FollowAlibaba Clouder - September 16, 2019
Alibaba Clouder - March 6, 2019
Alibaba Clouder - August 13, 2020
Alibaba Clouder - September 16, 2019
Alibaba Clouder - November 14, 2017
Alibaba Clouder - April 10, 2019
2,599 posts | 762 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreA secure, reliable, and elastically scalable cloud database service for automatic monitoring, backup, and recovery by time point
Learn MoreAn encrypted and secure cloud storage service which stores, processes and accesses massive amounts of data from anywhere in the world
Learn MoreMore Posts by Alibaba Clouder
5899807706397853 January 6, 2021 at 7:05 am
Is "47.88.230.255" the private IP address or the public IP address of the instance? How should someone visit the web app from a remote client? Just enter the public IP in the browser?