Skip to content

Instantly share code, notes, and snippets.

@rohitk5252
Created April 28, 2025 05:53
Show Gist options
  • Select an option

  • Save rohitk5252/1125a1e4431c3abbdf97964c2b70bc3c to your computer and use it in GitHub Desktop.

Select an option

Save rohitk5252/1125a1e4431c3abbdf97964c2b70bc3c to your computer and use it in GitHub Desktop.

Complete Node.js Deployment Guide: EC2, PM2, NGINX, and SSL

1. Create AWS Account

Create a free AWS account at https://aws.amazon.com/

2. Set Up EC2 Instance

Create and Launch EC2

  1. Log into AWS console and navigate to EC2
  2. Click "Launch Instance"
  3. Select Ubuntu Server (e.g., Ubuntu 22.04 LTS)
  4. Choose t2.medium instance type
  5. Configure instance details as needed

Generate SSH Key Pair

When creating your EC2 instance, AWS will prompt you to create or use an existing key pair:

  • Create a new key pair
  • Download the .pem file
  • Store it securely (e.g., ~/.ssh/myec2key.pem)

Set Proper Permissions for Key

chmod 400 ~/.ssh/myec2key.pem

Connect to EC2 Instance

ssh -i ~/.ssh/myec2key.pem ubuntu@your-ec2-public-ip

3. Install Node.js and NPM

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install nodejs -y
node --version
npm --version

4. Connect GitLab to EC2

Generate SSH Key on EC2

ssh-keygen -t rsa -b 4096 -C "[email protected]"
# Press Enter for default file location
# Create a passphrase if desired

Add SSH Key to SSH Agent

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

Add Public Key to GitLab

  1. Display your public key:
cat ~/.ssh/id_rsa.pub
  1. Copy the output
  2. In GitLab:
    • Go to your profile → Settings → SSH Keys
    • Paste the key and give it a title (e.g., "EC2 Deployment Server")
    • Click "Add key"

Test GitLab Connection

You should see a welcome message confirming successful authentication.

5. Clone Your Project

git clone [email protected]:your-username/your-repo.git
# or using HTTPS if you prefer
git clone https://gitlab.com/your-username/your-repo.git

# Navigate to project directory
cd your-repo

6. Install Dependencies and Configure App

# Install project dependencies
npm install

# If you have environment variables, set them up
cp .env.example .env  # If you have an example env file
nano .env  # Edit environment variables as needed

# Install PM2 globally
sudo npm install pm2 -g

# Start application with PM2
pm2 start index.js --name "your-app-name"

# Set PM2 to start on system boot
pm2 startup ubuntu
# Run the command that PM2 outputs
pm2 save

7. Set Up Firewall

sudo ufw enable
sudo ufw status
sudo ufw allow ssh  # Port 22
sudo ufw allow http  # Port 80
sudo ufw allow https  # Port 443

8. Install and Configure NGINX

sudo apt install nginx -y

# Create site configuration
sudo nano /etc/nginx/sites-available/yourdomain.com

Add the configuration:

server {
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:8001;  # Update this to your app's port
        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;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
sudo nginx -t  # Test configuration
sudo systemctl restart nginx

9. Point Domain to EC2 Instance

  1. Go to your domain registrar
  2. Create an A record pointing to your EC2 public IP address:
    • Host: @ (or subdomain if using one)
    • Value: Your EC2 public IP
    • TTL: 3600 (or as desired)
  3. If using www subdomain, create another A record or a CNAME

10. Install SSL with Let's Encrypt

sudo apt update
sudo apt install python3 python3-venv libaugeas0 -y

# Setup Python environment
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip

# Install Certbot
sudo /opt/certbot/bin/pip install certbot certbot-nginx

# Create symbolic link
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

# Obtain SSL certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Follow prompts to complete certificate installation

11. Set Up Auto-Renewal for SSL Certificate

Let's Encrypt certificates expire after 90 days, so set up auto-renewal:

sudo crontab -e

Add this line:

0 3 * * * /usr/bin/certbot renew --quiet

This will attempt renewal at 3 AM daily (but will only renew when needed).

12. Continuous Deployment (Optional)

If you want automated deployments when you push to GitLab:

  1. Create a deployment script:
nano ~/deploy.sh
  1. Add deployment commands:
#!/bin/bash
cd ~/your-repo
git pull
npm install
pm2 restart your-app-name
  1. Make it executable:
chmod +x ~/deploy.sh
  1. Set up GitLab CI/CD or a webhook to trigger this script when changes are pushed.

Troubleshooting Tips

  • Check NGINX logs: sudo tail -f /var/log/nginx/error.log
  • Check your app logs: pm2 logs your-app-name
  • If you can't connect: verify security groups in AWS allow ports 22, 80, and 443
  • DNS issues: Run dig yourdomain.com to verify DNS is pointing to the correct IP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment