First, update the package list and upgrade existing packages:
sudo apt update
sudo apt upgrade
Add the Node.js PPA (Personal Package Archive) to get the latest version of Node.js:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
Then install Node.js npm and git:
sudo apt install nodejs -y
sudo apt install npm -y
sudo apt install git -y
Verify Node.js and npm Installation:
node -v
npm -v
Step 3: Transfer the project files (clone with SSH)
Step 4: Transfer the project files (clone with SSH)
Step 4.1: Install project dependencies Navigate to your Project Directory
cd your-repo-name
npm install
Step 5: Setup environment variables Create the Environment File
sudo vim /etc/app.env
i. Add your variables
In Vim, add your variables in the format VARIABLE=value. For example:
PORT=3000
Press i to enter insert mode in vim Paste the environment variables Press Escape to exit the mode Enter: :x to save and exit
ii. Restrict the file permissions for security.
sudo chmod 600 /etc/app.env
sudo chown ubuntu:ubuntu /etc/app.env
Step 6: Run the server in background We want our node.js server to run in the background, i.e.: when we close our terminal we want our server to keep running
For this purpose, we need a Daemon Service A daemon is a background process or program that is designed to perform tasks without any direct user intervention
We can create a daemon service using systemd.
Nearly every Linux distro comes with systemd, which means forever, monit, PM2, etc are no longer necessary — your OS already handles these tasks.
Creating a daemon service with systemd involves writing a script for the daemon process and creating a service file for systemd to manage it.
A systemd service file is a unit configuration file that defines how systemd starts and manages a certain background service.
Create the systemd Service File Navigate to the systemd directory and create a new service file, myapp.service.
sudo vim /etc/systemd/system/myapp.service
6.1 Define the service settings
Add the following content in Vim, modifying as needed for your application.
[Unit]
Description=Node.js App
After=network.target multi-user.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/app
ExecStart=/usr/bin/npm start
Restart=always
Environment=NODE_ENV=production
EnvironmentFile=/etc/app.env
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target
Change the Description as per your app name. Change the WorkingDirectory to /home/ubuntu/your-repo-name
There are different ways to start a Node.js application, depending on your project setup. Change the ExecStart to /usr/bin/project_start_command For example: npm start or node server.js or nodemon server.js
Change the SyslogIdentifier to project name for logging purposes
6.2 Reload systemd and start your service.
sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service
Verify that the service is running properly.
sudo systemctl status myapp.service
Step 7: Set Up a Reverse Proxy with Nginx A reverse proxy is a server that sits between client devices and web servers, forwarding client requests to the appropriate server.
When a client sends a request to a website, the reverse proxy intercepts this request and forwards it to the backend server (in this case, the Node.js application running on port 3000).
The backend server processes the request and sends the response back to the reverse proxy, which then forwards it to the client.
Why a reverse proxy is commonly used and why the Node.js application was not directly run on ports 80 or 443:
On many operating systems, binding to ports below 1024 (such as 80 and 443) requires elevated privileges (root access) A reverse proxy can distribute incoming requests across multiple instances of the Node.js application, improving load balancing and allowing the system to scale horizontally Running the application behind a reverse proxy helps isolate it from direct exposure to the internet. This provides an additional layer of security. A reverse proxy like Nginx or Apache is more efficient at handling a large number of incoming requests, static content, and SSL/TLS encryption.
In this tutorial, we’ll use Nginx for reverse proxy
Install Nginx
sudo apt install nginx
Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
- Verify that Nginx is installed
Go to the VM’s public IP Address. You can find that in network of the instance dashboard
If you see this, it means that nginx is installed correctly
- Configure Nginx as a Reverse Proxy
Create a new configuration file for your Node.js application. You can place this file in the /etc/nginx/sites-available directory. For example, create a file called nodeapp
sudo nano /etc/nginx/sites-available/nodeapp
Add the following configuration to the file:
server {
listen 80;
server_name your_domain_or_IP;
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;
}
}
7.2 Enable the Configuration
Create a symbolic link to enable the configuration:
sudo ln -s /etc/nginx/sites-available/nodeapp /etc/nginx/sites-enabled/
Test the Nginx configuration for syntax errors:
sudo nginx -t
If there are no errors, restart Nginx to apply the changes:
sudo systemctl restart nginx
- Adjust Firewall Rules
Ensure that your firewall allows HTTPS traffic:
sudo ufw allow 'Nginx Full'
- Verify the setup
Open your web browser and navigate to http://IP. You should see your Node.js application, indicating that Nginx is successfully proxying requests to your application running on port 3000.
Step 11: Obtain SSL/TLS Certificate (Optional Step) You need to obtain a SSL/TLS Certificate inorder to use HTTPS instead of HTTP.
Also we need to configure nginx such that, if the user visits http then they should be redirect to https
Using Let’s Encrypt with a Domain Name
11.1 Using Let’s Encrypt with a Domain Name For this step, you require a domain name because many Certificate Authorities, including Let's Encrypt, prefer or require a domain name to issue SSL/TLS certificates
Purchase a Domain Name: You can buy a domain name from registrars like Namecheap, GoDaddy, or Google Domains
- Point the Domain to Your Server:
Set up an A record in your domain’s DNS settings to point to your server’s IP address. You can do this using Amazon Route 53
- Complete the Configuration:
Install Certbot and the Nginx plugin Certbot will help you obtain and manage SSL/TLS certificates from Let’s Encrypt:
sudo apt install certbot python3-certbot-nginx
- Obtain an SSL/TLS Certificate
Obtain an SSL/TLS Certificate
sudo certbot --nginx -d your_domain_or_IP
- Configure Nginx to Redirect HTTP to HTTPS
Open the Nginx configuration file for your site:
sudo nano /etc/nginx/sites-available/nodeapp
Modify the configuration to include both the HTTP to HTTPS redirect and the HTTPS server block. Your updated configuration should look like this:
server {
listen 80;
server_name your_domain_or_IP;
# Redirect all HTTP requests to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your_domain_or_IP;
ssl_certificate /etc/letsencrypt/live/your_domain_or_IP/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain_or_IP/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
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;
}
}
Make sure to replace your_domain_or_IP with your actual domain name or IP address
- Remove default config
sudo rm /etc/nginx/sites-enabled/default
- Enable the Configuration and Restart Nginx
sudo ln -s /etc/nginx/sites-available/nodeapp /etc/nginx/sites-enabled/
- Test the Nginx configuration
sudo nginx -t
- If there are no errors, restart Nginx to apply the changes:
sudo systemctl restart nginx
- Adjust Firewall Rules (if necessary)
sudo ufw allow 'Nginx Full'
- Verify the setup
Open your web browser and navigate to http://your_domain. You should be automatically redirected to https://your_domain and see your Node.js application served securely.