
Managing Digitalux on AWS EC2 with Hostinger: Powerful Lessons Learned
Deploying and managing a secure and scalable infrastructure is a critical part of running any digital business. At Digitalux, we
Deploy Node.js App on AWS EC2 (Elastic Compute Cloud) is a service provided by Amazon Web Services that allows users to rent virtual servers (instances) to run applications on demand. It provides flexibility, scalability, and cost-effectiveness, making it an excellent choice for hosting Node.js applications. Node.js is an event-driven, non-blocking I/O model that is ideal for building scalable network applications.
Node.js, on the other hand, is an asynchronous, event‑driven JavaScript runtime designed to build scalable network applications. It handles many concurrent connections through an event loop without spawning operating‑system threads or locking resources; almost no function performs I/O directly, so the process rarely blocks. Because nothing blocks, “scalable systems are very reasonable to develop in Node.js, and HTTP support is built in with streaming and low‑latency communication in mind.
This guide will walk you through the process of deploying a Node.js app on an AWS EC2 instance. It’s aimed at developers and system administrators who want to deploy their Node.js applications on AWS EC2 instances for production environments.
Also read our other blog: A Step-by-Step Guide to Deploying Mattermost on AWS
We choose AWS EC2 for Node.js Deployment because of the following reasons:
The benefits of deploying Node.js App on AWS EC2 are as under:
Step 1: Setting Up AWS EC2 Instance
The first step in deploying your Node.js app is setting up an EC2 instance. Here’s how to do it:
After configuring your instance, click Launch. You can now connect to the EC2 instance via SSH.
To access your EC2 instance, follow these steps:
chmod 400 your-key.pem
ssh -i your-key.pem ec2-user@your-ec2-public-ip # Amazon Linux
Or for Ubuntu:
chmod 400 your-key.pem
ssh -i your-key.pem ubuntu@your-ec2-public-ip # Ubuntu
# For Amazon Linux
sudo yum update -y
# For Ubuntu
sudo apt update && sudo apt upgrade -y
Now, let’s install Node.js and NPM (Node Package Manager).
Method: Using NodeSource Repository
(Works for Ubuntu/Debian-based distributions — for other distros, adjust accordingly.)
sudo apt update
sudo apt upgrade -y
2. Install curl if not already installed:
sudo apt install curl -y
3. Add NodeSource repository for the LTS version:
curl -fsSL <https://deb.nodesource.com/setup_lts.x> | sudo -E bash -
4. Install Node.js (includes npm):
sudo apt install -y nodejs
5. Verify installation:
node -v
npm -v
6. Install Node Version Manager (nvm):
curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh> | bash
source ~/.bashrc
Now you need to activate nvm by using the command :
#. ~/.nvm/nvm.sh
7. Install Node.js using nvm:
nvm install --lts
nvm use --lts
node -v
npm -v
nvm allows you to install and manage different versions of Node.js, which is useful for managing dependencies in different environments.
If your Node.js app’s source code is stored in a GitHub repository, you’ll first need to download it onto your EC2 instance.
sudo apt install git -y # For Ubuntu/Debian
sudo yum install git -y # For Amazon Linux/CentOS
2. Clone your repository
Replace the URL with your own repository’s HTTPS or SSH link:
git clone <https://github.com/your-username/your-repo-name.git>
3. Move into the project directory
cd your-repo-name
After cloning your application, you’ll need to install its required packages using npm (which comes with Node.js).
package.json file in your project and install all listed dependencies:npm install
node_modules folder is created and that there are no major errors in the output..env file), create or upload it to the project directory:nano .env
Add your environment keys and values, then save.
Before moving on to production setup:
node app.js
or if your entry file is different:
node server.js
Check in your browser using:
<http://your-ec2-public-ip:3000>
(Replace 3000 with the port your app uses.)
A reverse proxy acts as an intermediary between clients (e.g., browsers) and your Node.js application.
Now, let’s set up Nginx as a reverse proxy for your Node.js application. This allows you to handle incoming traffic on HTTP/HTTPS ports and forward it to your Node.js application.
sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
sudo yum install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
Security group note:
In your AWS EC2 console, ensure your instance’s Security Group allows inbound traffic on:
Edit the /etc/nginx/nginx.conf or create a new config file under /etc/nginx/sites-available:
You’ll configure Nginx to listen on port 80 and forward requests to your Node.js app running locally (e.g., on port 3000).
Ubuntu/Debian (sites-available / sites-enabled method)
sudo nano /etc/nginx/sites-available/yourdomain.com
Paste:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
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_cache_bypass $http_upgrade;
}
}
Enable the config:
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # optional, to remove default site
Amazon Linux / CentOS (conf.d method)
sudo nano /etc/nginx/conf.d/yourdomain.conf
Paste the same server { … } block above.
Check configuration syntax:
sudo nginx -t
Reload to apply changes:
sudo systemctl reload nginx
Your Node.js app should listen only on localhost for security:
app.listen(3000, '127.0.0.1', () => {
console.log('App running on http://127.0.0.1:3000');
});
http://yourdomain.com (or your EC2 public IP if no domain yet)./var/log/nginx/error.loga) Get your EC2 Public IP
b) Update DNS Records
@ (root domain) → point to your EC2 public IP.www → point to the same IP (optional).c) Allow Time for Propagation
nslookup yourdomain.com
We’ll use Certbot to get a free SSL/TLS certificate.
a) Install Certbot and Nginx Plugin
Ubuntu/Debian
sudo apt update
sudo apt install -y snapd
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
Amazon Linux / RHEL / CentOS
sudo yum install -y snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
b) Get the Certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
If you used the --nginx option, Certbot auto-configures Nginx.
Your secure server block will look like this:
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
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_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
This forces all HTTP traffic to redirect to HTTPS.
Test certificate:
https://yourdomain.com — look for the secure lock icon.Dry-run renewal check:
sudo certbot renew --dry-run
Let’s Encrypt certificates are valid for 90 days. Certbot will install a cron job or systemd timer to auto-renew them.
PM2 is a process manager for Node.js applications. It keeps your app running in the background, restarts it if it crashes, and can auto-start it when the server reboots.
Install PM2 globally with npm:
sudo npm install -g pm2
Verify installation:
pm2 -v
Navigate to your project directory (where your main file like app.jsor server.js is located), then start the app with PM2:
cd /home/ec2-user/your-node-app
pm2 start app.js --name "my-node-app"
app.js → replace with your main entry file.-name → gives your app a readable name for easier management.Common commands:
pm2 list → shows all running processes.pm2 status → check status of your apps.pm2 logs my-node-app→ view real-time logs.pm2 stop my-node-app → stop the app.pm2 restart my-node-app → restart the app.By default, if your EC2 instance reboots, the Node.js app will stop running. PM2 can configure a startup script to solve this.
Run the following command:
pm2 startup systemd
This will output a command tailored to your system. Copy and run it (it usually looks like this):
sudo env PATH=$PATH:/home/ec2-user/.nvm/versions/node/$(node -v)/bin pm2 startup systemd -u ec2-user --hp /home/ec2-user
Now save your current PM2 process list so it restarts automatically after reboot:
pm2 save
Test by rebooting your instance:
sudo reboot
After logging back in, check with:
pm2 list
Your app should still be running.
This ensures your Node.js application stays alive 24/7 and recovers automatically from crashes or reboots.
Security Groups are AWS-level firewalls applied to your EC2 instance.
0.0.0.0/0).This minimizes exposure to unwanted connections.
Besides AWS security groups, you can enable the instance’s own firewall for an extra layer of defense.
sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full' # allows ports 80 and 443
sudo ufw enable
sudo ufw status
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
/etc/ssh/sshd_config and set:PermitRootLogin no
Then restart SSH:
sudo systemctl restart sshd
# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
# Amazon Linux
sudo yum update -y
sudo apt install fail2ban -y # Ubuntu/Debian
Amazon CloudWatch lets you track performance metrics and system health.
a) Enable CloudWatch Agent
sudo yum install -y amazon-cloudwatch-agent
sudo apt-get update
sudo apt-get install -y amazon-cloudwatch-agent
2. Configure the agent interactively:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
3. Start the agent:
sudo systemctl enable amazon-cloudwatch-agent
sudo systemctl start amazon-cloudwatch-agent
4. Check metrics in the AWS CloudWatch Console under EC2 > Metrics.
This helps you detect CPU spikes, memory leaks, or abnormal traffic patterns before they crash your app.
Since your Node.js app is running under PM2, you can use its built-in log management.
a) Viewing logs in real-time
pm2 logs my-node-app
b) Checking only errors
pm2 logs my-node-app --lines 100 --err
c) Log file locations
PM2 stores logs in files inside:
~/.pm2/logs/
You’ll find two files per app:
my-node-app-out.log (standard output)my-node-app-error.log (errors only)d) Monitoring performance with PM2
pm2 monit
pm2 logrotate module: pm2 install pm2-logrotate
Deploying a Node.js application on AWS EC2 may seem like a long journey at first, but by breaking it into clear steps, the process becomes both manageable and rewarding. Hosting Node.js on AWS gives you full control over your environment while providing scalability and flexibility. With EC2 and Node.js’s event-driven architecture, you can handle high concurrency and deliver a performant app to your users. By following this step-by-step guide, you’ve set up a robust, production-ready application with reverse proxy, SSL, and process management using PM2.
In short, you’ve built the foundation for a robust deployment workflow—one that empowers you to deliver your Node.js applications to users across the globe with speed, stability, and confidence.
Explore other blogs for better understanding: Deploying NodeJS APP on AWS EC2 Instance — Step by Step

Deploying and managing a secure and scalable infrastructure is a critical part of running any digital business. At Digitalux, we

Introduction: At Digitalux, we constantly strive to enhance team productivity by integrating powerful tools into our workflows. In modern work

Introduction: Securing a website with an SSL certificate is essential for data protection, trust, and improved SEO rankings. Automatic SSL
2024@Digitalux All right reserved