Steps to deploy a Node.js app to DigitalOcean using PM2, NGINX as a reverse proxy and an SSL from LetsEncrypt
I will be using the root user, but would suggest creating a new user
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install nodejs
node --version
There are a few ways to get your files on to the server, I would suggest using Git
git clone yourproject.git
cd yourproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C
sudo npm i pm2 -g
pm2 start app (or whatever your file name)
# 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)
sudo ufw enable
sudo ufw status
sudo ufw allow ssh (Port 22)
sudo ufw allow http (Port 80)
sudo ufw allow https (Port 443)
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 / {
proxy_pass http://localhost:5000; #whatever port your app runs on
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
In Digital Ocean, go to networking and add a domain
Add an A record for @ and for www to your droplet
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
- Add SSL with LetsEncrypt
# make sure u are using up to date snap
sudo snap install core; sudo snap refresh core
# remove any existing certbot packages to use one from snap
sudo apt-get remove certbot
# install certbot from snap
sudo snap install --classic certbot
# prepare certbot command
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# create certificates with auto config from certbot in nginx
sudo certbot --nginx
# auto renewal of certificate after 90 days
sudo certbot renew --dry-run