Deploy Nodejs app on AWS EC2 Server
These are the following steps we will follow.
- Login to AWS server using
terminal
and usingtermius
app. - Server setup for deployment.
- Run node js app with
pm2
to keep alive. - Setup
Nginx
and domain cofiguration. - Add free SSL certificate with
Let's Encrypt
. - Configure domain in
nginx
forhttps
. - Bonus Step:
Configuration for Next.js & React js | SPA
Requirements:
I’m assuming you already have aws account and server details, and you need these credentials ip address
, username
, password or pem file
, and a domain
.
Step 1.
Login to aws account in terminal using ssh
. 🔗
if you have password
instead of pem
file then try this.
$ ssh username@ip_address
Example: ssh ubuntu@192.168.3.103
// it will ask you the password once you run this command
if you don’t have password, you have .pem
file then try this.
$ ssh -i file.pem username@ip_address
Example: ssh -i aws_key.pem ubuntu@192.168.3.103 // use sudo if required
Login using termius:
if you have .pem
file, you need to upload it on termius, click on setting icon ⚙️ on top left corner. select Keychain
click on 🗝️key
and click on Drag and drop a private key fine to import
and upload you pem file.
For this you need to install termius app first and go to Host
section in left sidebar, click on New Host
, a prompt will open in right sidebar, fill your IP Address
, add Username
, & Password
that’s it and click on ⇥ top right corner.
if you don’t have password then select key option below password, one key input will be visible there. ( before that you need to add a pem file to termius ) select your pem file and go next, you don’t need to add password.
Step 2
Once you login to the server, run command sudo su
to enter into sudo.
Install all required dependencies — nodejs
npm
nginx
pm2
git
# Update apt package index
sudo apt update
# Install curl if not already installed
sudo apt install -y curl
# Install Node.js and npm from NodeSource repository
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install Nginx
sudo apt-get install -y nginx
sudo ufw allow 'Nginx HTTP'
sudo service nginx start
sudo systemctl enable nginx
# Install PM2
sudo npm install -g pm2
# Install git
sudo apt install git
Step 3
Clone you Nodejs repository inside /var/www/html/
this path is recommended not mandatory you can clone anywhere.
Once you clone your repo, setup all your env and install dependencies ( complete your project setup ) and run a production build. ( assuming your node app is running on port 8000
)
Note: to access your port on ip like this
http://192.168.3.153:8000
, you need to add this port to yourAWS security group’s inbound rule
. make sure you did this if you want to use your app withip:port
To run your node app with pm2
run this script:
# if you have a file to run use this
$ pm2 start server.js --name "node_api:8000"
# if you want to run a script using pm2
$ pm2 start npm --name "node_api:8000" --run "start"
# here --name <name to your pm2 instance> & --run <script to run your app>
Step 4 ( Manual domain configuration )
Note: you can skip this step if you want to use
Let’s encrypt
free SSL certificate
First thing you need is a domain and you need to add this server ip to your domain provider ( go to dns configuration
> add new dns record
> select type: A
, Name: your subdoamin
, points to: ip address
).
Note: this may take few time to whitelist your ip on DNS
Open nginx default configuration file:
First navigate to /etc/nginx/sites-available
and open default
file with nano
editor — and add the below
For http
# configutaion for http only
server {
listen 80;
listen [::]:80;
server_name website.com;
location / {
proxy_pass http://localhost:8000;
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;
}
}
For https ( with custom SSL certificates )
# configuration for https with ssl certificates
server {
listen [::]:443 ssl;
listen 443 ssl;
server_name website.com;
ssl_certificate /etc/ssl/myApp/website_com.crt;
ssl_certificate_key /etc/ssl/myApp/server.key;
location / {
proxy_pass http://localhost:8000;
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;
}
}
# add this for automatically redirect http request to https
server {
if ($host = website.com) {
return 301 https://$host$request_uri;
}
listen 80 ;
listen [::]:80 ;
server_name staging.website.com;
return 404;
}
Step 5 & 6 ( domain configuration with let’s encrypt )
Note: you can skip this step if you want to use your custom ssl certificate.
Secure your domain with let’s encrypt (read this document)
- Install Certbot
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt install python3-certbot-nginx
# if this line don't work for you use python-certbot-nginx
# verify nginx configuration
$ sudo nginx -t
2. Obtaining SSL Certificate
$ sudo certbot --nginx -d example.com -d www.example.com
3. Verify Certbot Auto-Renewal
$ sudo certbot renew --dry-run
Note: the above step 3 will automatically generate ssl configuration and add certificate for that domain. you need to run this command every time for each sub domain you want to add and get new certificate for that sub domain.
→ to add certificate only on sub domain add-d subdomain only
$ sudo certbot --nginx -d staging.example.com
Note: after this you need to modify nginx configuration according to your requirements ( You can follow Step 4 for this ).
Most probably you need to update server location
location / {
proxy_pass http://localhost:8000;
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;
}
Once you done with all configuration and everything, restart your nginx sudo service nginx restart
or for mac: brew services restart nginx
.
7. Bonus Step
a. Deploy Next js code
You can follow the same steps for next js also, as in next js you need to run a server on a port.
b. Deploy React Js or Single Page Application
( react, angular, view, html pages, etc. )
For React js, you may follow all the steps but you don’t need pm2 and you don’t need to start your server because you just need the path of your html file in your build.
Your configuration will be like this
server_name my-website.com;
# path to your build html file. & make sure there is a html file inside
root /var/www/html/react-website/build;
# add this line tell nginx to detect one of these files
index index.html index.htm index.nginx-debian.html;
# in location add this only
location / {
try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
}
}
Thank you 🙏
Happy Coding 😊
👨💻👨💻👨💻👨💻👨💻