Skip to content

Instantly share code, notes, and snippets.

@multiahfoon
Forked from bradtraversy/node_nginx_ssl.md
Last active July 14, 2021 02:57
Show Gist options
  • Select an option

  • Save multiahfoon/81cf5fefdae86e38229f79c762031883 to your computer and use it in GitHub Desktop.

Select an option

Save multiahfoon/81cf5fefdae86e38229f79c762031883 to your computer and use it in GitHub Desktop.
Node app deploy with nginx & SSL

Node.js Deployment

Steps to deploy a Node.js app to DigitalOcean using PM2, NGINX as a reverse proxy and an SSL from LetsEncrypt

1. Sign up for Digital Ocean

If you use the referal link below, you get $10 free (1 or 2 months) https://m.do.co/c/5424d440c63a

2. Create a droplet and log in via ssh

I will be using the root user, but would suggest creating a new user

3. Install Node/NPM

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs

node --version
npm --version

4. Clone your project from Github

There are a few ways to get your files on to the server, I would suggest using Git

git clone yourproject.git

5. Install dependencies and test app

cd yourproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C

6. Setup PM2 process manager to keep your app running

sudo npm i pm2 -g
pm2 start app (or whatever your file name)
# or for scripts in package.json 
pm2 start "npm run dev" --name appName # 'appName' will show up in status


# Other pm2 commands
pm2 show app
pm2 status
pm2 restart app
pm2 stop app
pm2 logs # Show log stream
pm2 flush # Clear logs

# To make sure app starts when reboot
pm2 startup ubuntu

You should now be able to access your app using your IP and port. Now we want to setup a firewall blocking that port and setup NGINX as a reverse proxy so we can access it directly using port 80 (http)

7. Setup ufw 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 NGINX and configure

sudo apt install nginx

sudo nano /etc/nginx/sites-available/default

Add the following to the location part of the server block

    server_name yourdomain.com www.yourdomain.com;

    location / {
        # If nginx is run on the same server as app, set app port to something other than 80
        proxy_pass http://localhost:3000; # Example, the assigned port in your app
        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;
    }
# Check NGINX config
sudo nginx -t

# Restart NGINX
sudo service nginx restart

You should now be able to visit your IP with no port (port 80) and see your app. Now let's add a domain

9. Add domain in Digital Ocean

In Digital Ocean, go to networking and add a domain

Add an A record for @ and for www to your droplet

Register and/or setup domain from registrar

I prefer Namecheap for domains. Please use this affiliate link if you are going to use them https://namecheap.pxf.io/c/1299552/386170/5618

Choose "Custom nameservers" and add these 3

  • ns1.digitalocean.com
  • ns2.digitalocean.com
  • ns3.digitalocean.com

It may take a bit to propogate

  1. Add SSL with LetsEncrypt

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot # Prepare the Certbot command
sudo certbot --nginx # You will be prompt to pick a domain, leave input emty to pick all

# Only valid for 90 days, test the renewal process with
sudo certbot renew --dry-run 


Now visit https://yourdomain.com and you should see your Node app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment