✨ Featured Insight

How to Deploy a Node.js App on EC2 with Apache or Nginx (with & without PM2)

A complete Node.js deployment guide with HTTPS, PM2, and server configurations on AWS EC2.

1. Launch EC2 Instance & Connect

  • Choose Ubuntu 22.04 or Amazon Linux 2
  • Open ports: 22 (SSH), 80 (HTTP), 443 (HTTPS)
  • SSH into your EC2 instance:
    ssh -i "your-key.pem" ec2-user@your-ec2-ip

2. Install Node.js & Git


curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs git
node -v
npm -v
          

3. Clone Your Node.js App


git clone https://github.com/yourusername/your-node-app.git
cd your-node-app
npm install
node app.js # or whatever your entry point is
          

4. Option A: Run With PM2


sudo npm install -g pm2
pm2 start app.js
pm2 startup
pm2 save
          

🔧 Setup systemd Service (PM2 Docker Version)


[Unit]
Description=PM2 Node.js App
After=network.target

[Service]
User=ec2-user
Restart=always
Environment=PATH=/usr/bin:/usr/local/bin
WorkingDirectory=/home/ec2-user/your-node-app
ExecStart=/usr/bin/pm2 start app.js --name "nodeapp"
ExecReload=/usr/bin/pm2 reload all
ExecStop=/usr/bin/pm2 stop all

[Install]
WantedBy=multi-user.target
          

sudo systemctl daemon-reexec
sudo systemctl enable nodeapp
sudo systemctl start nodeapp
          

5. Option B: Run Without PM2

node app.js &

6. Apache (httpd) as Reverse Proxy with HTTPS


sudo apt update
sudo apt install apache2 -y
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
          
sudo nano /etc/apache2/sites-available/your-node-app.conf

<VirtualHost *:80>
  ServerName yourdomain.com

  ProxyPreserveHost On
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    ServerName yourdomain.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem

    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
  </VirtualHost>
</IfModule>
          

sudo a2ensite your-node-app
sudo systemctl reload apache2
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache
          

7. Nginx as Reverse Proxy


sudo apt install nginx -y
          
sudo nano /etc/nginx/sites-available/your-node-app

server {
  listen 80;
  server_name yourdomain.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;
  }
}
          

sudo ln -s /etc/nginx/sites-available/your-node-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx
          

🔒 Secure with HTTPS


sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
          

8. Final Tips

  • Use .env for secrets and configs
  • Monitor app logs using pm2 logs
  • Ensure firewall rules allow ports 80/443

🎉 Congrats! Your Node.js app is now live on AWS EC2 with a secure production setup.