Steps to deploy a Node.js app to DigitalOcean using PM2, NGINX as a reverse proxy and an SSL from LetsEncrypt
If you use the referal link below, you get $10 free (1 or 2 months) https://m.do.co/c/5424d440c63a
I will be using the root user, but would suggest creating a new user
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version
npm --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)
# 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)
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 / {
# 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
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
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