The Ultimate Guide to Hosting a Node.js App on AWS (2026 Edition)
Are you a web developer looking to host your Node.js application in a scalable, reliable, and cost-effective way? If so, Amazon Web Services (AWS) is an excellent choice. AWS provides a comprehensive set of tools and services that make it easy to deploy, manage, and scale Node.js apps.
In this guide, we‘ll walk through the process of hosting a Node.js app on AWS from start to finish. Whether you‘re new to AWS or a seasoned pro, this guide will provide you with everything you need to know to get your Node.js app up and running on AWS. Let‘s get started!
Prerequisites
Before we dive in, let‘s go over a few prerequisites you‘ll need:
- An AWS account (you can create one for free at https://aws.amazon.com)
- Node.js and npm installed on your local machine
- Basic familiarity with the command line/terminal
- A text editor for editing code (VS Code, Sublime, etc.)
We‘ll also be using a few AWS services throughout this guide, but don‘t worry if you‘re not already familiar with them. I‘ll explain each one as we go.
Step 1: Set up an EC2 Instance
The first step is to launch a new EC2 instance that will serve as the server for our Node.js app. EC2 (Elastic Compute Cloud) is the AWS service that provides resizable compute capacity in the cloud.
Here‘s how to launch a new EC2 instance:
- Log in to the AWS Management Console and navigate to the EC2 dashboard.
- Click the "Launch Instance" button.
- Choose an Amazon Machine Image (AMI) – for this guide, we‘ll use the Amazon Linux 2 AMI.
- Choose an instance type – a t2.micro instance will be sufficient for our purposes (and is eligible for the free tier).
- Configure the instance details – you can use the default settings for most options, but make sure to select "Enable" for Auto-assign Public IP.
- Add storage – the default 8GB is enough for our app.
- Add tags – this is optional but can help with organizing your resources.
- Configure the security group – this is an important step! We‘ll need to open up port 80 (HTTP) and 443 (HTTPS) so that traffic can reach our instance. You can restrict the Source to your own IP for added security.
- Review and launch the instance. You‘ll be prompted to create or select a key pair – make sure to download and save this somewhere secure as you‘ll need it to SSH into the instance.
Once the instance is launched, make a note of its public DNS name as we‘ll need that later. It will look something like ec2-12-345-678-90.compute-1.amazonaws.com.
Step 2: Connect to the EC2 Instance and Prepare It for Node.js
Now that we have our EC2 instance up and running, the next step is to connect to it and get it set up for our Node.js app.
To connect to the instance, open up your terminal and navigate to the directory where you saved your key pair file. Then run the following command (replacing the placeholder with your own instance details):
ssh -i "your-key-pair.pem" [email protected]
You should now be logged in to the EC2 instance!
Before we install Node.js, let‘s make sure the instance has the latest updates:
sudo yum update
Once that finishes, we can install Node.js. We‘ll use the Node Version Manager (nvm) to do so:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
Activate nvm:
. ~/.nvm/nvm.sh
Use nvm to install the latest version of Node.js:
nvm install node
Verify that Node.js and npm are installed correctly:
node -v
npm -v
The instance is now ready for our Node.js app!
Step 3: Deploy a Sample Node.js App
For demonstration purposes, we‘ll create a simple "Hello World" Node.js app using the Express web framework. Of course, you can deploy your own app here instead.
First, create a new directory for the app:
mkdir hello-world
cd hello-world
Initialize a new Node.js project:
npm init -y
Install Express:
npm install express
Create a new file called index.js with the following code:
const express = require(‘express‘)
const app = express()
app.get(‘/‘, (req, res) => {
res.send(‘Hello, World!‘)
})
const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
This code sets up a basic Express server that listens on port 3000 and responds with "Hello, World!" when the root URL is requested.
Start the app:
node index.js
The app should now be running on the EC2 instance at http://ec2-12-345-678-90.compute-1.amazonaws.com:3000 (replace with your instance‘s public DNS). But if you try to visit that URL in your browser, you‘ll get an error because port 3000 is not open in the security group.
To fix that, go back to the EC2 dashboard, select the instance, click the security group, and edit the inbound rules to allow custom TCP traffic on port 3000 from anywhere (0.0.0.0/0 or ::/0 for IPv4 and IPv6 respectively).
Now if you visit http://ec2-12-345-678-90.compute-1.amazonaws.com:3000 you should see the "Hello, World!" message.
Step 4: Set up Nginx as a reverse proxy
While our app is now working, serving it directly from Node.js on port 3000 isn‘t ideal for a few reasons:
- Port 3000 isn‘t a standard web port, so URLs look odd.
- If/when we want to add more apps to this server, they would each need their own port.
- Node.js isn‘t as efficient as some other web servers at serving static assets.
- We can‘t yet use SSL/HTTPS, which is essential for security.
To solve these issues, we‘ll set up Nginx as a reverse proxy for our Node.js app.
Install Nginx:
sudo yum install nginx
Start Nginx:
sudo service nginx start
If you visit your EC2 instance‘s public DNS in the browser, you should now see the default Nginx landing page, as it listens on port 80 by default.
Now let‘s configure Nginx to proxy requests to our Node.js app. Open the default Nginx config file:
sudo nano /etc/nginx/nginx.conf
Find the server block and replace it with the following:
server {
listen 80;
server_name ec2-12-345-678-90.compute-1.amazonaws.com;
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;
}
}
This tells Nginx to listen on port 80 and proxy any requests to http://localhost:3000, which is where our Node.js app is running. The additional proxy_ directives are necessary for some WebSocket functionality in Express apps.
Save and exit the file, then restart Nginx for the changes to take effect:
sudo service nginx restart
Now if you visit http://ec2-12-345-678-90.compute-1.amazonaws.com (without the port number), you should see your app! Nginx is now proxying requests on port 80 to the Node.js app running on port 3000.
Step 5: Configure SSL with Let‘s Encrypt
The final step for a production-ready setup is to configure SSL/HTTPS. We‘ll use a free SSL certificate from Let‘s Encrypt via Certbot.
First, install Certbot:
sudo yum install certbot python3-certbot-nginx
To confirm Nginx‘s configuration is okay to proceed, run:
sudo certbot --nginx --register-unsafely-without-email
Note that we‘re using the --register-unsafely-without-email flag to avoid providing an email, but in a real setup, you should provide one.
Certbot will guide you through the process of obtaining and installing the SSL cert. It will ask if you want to redirect all HTTP traffic to HTTPS – select yes for better security.
Once it finishes, try visiting your site with https:// – it should work and show the secure padlock icon!
Certbot will automatically renew the SSL cert when needed, but it‘s a good idea to test the renewal process:
sudo certbot renew --dry-run
If you don‘t see any errors, auto-renewal is working.
Wrapping up
Congratulations! You now have a Node.js app securely deployed to AWS using industry best practices. To recap, we:
- Launched a new EC2 instance
- Connected to the instance and installed Node.js
- Deployed a sample Express.js app
- Configured Nginx as a reverse proxy
- Set up HTTPS with a free SSL certificate from Let‘s Encrypt
Of course, this is just the beginning. There are many additional steps you can take to further improve your app‘s performance, scalability, and maintainability on AWS, such as:
- Using a process manager like PM2 to run your app
- Storing static assets in S3
- Leveraging a managed database service like RDS
- Implementing caching with ElastiCache or CloudFront
- Setting up a CI/CD pipeline for automated deployments
- Configuring load balancing and autoscaling
- Monitoring and logging with CloudWatch
I encourage you to explore these and other AWS services as you continue on your cloud journey. And most importantly – get hands-on practice! The best way to really learn this stuff is by doing.
I hope this guide was helpful! If you have any questions or comments, feel free to reach out. Happy coding!