This is a checklist for setting up a VPS for a nodejs application using pm2 and caddy.
[ ] SSH into the server. If you are using a cloud provider, you can find the public IP address in the console. You should either have the server’s private key or your local machine’s public key should be added to the server’s authorized keys. Here we assume the second case.
ssh <username>@<public_ip_address>
# Eg. ssh [email protected]
[ ] Setup firewall
sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
If you are using a cloud provider, you may also need to configure the firewall on their end.
[ ] Update packages list
sudo apt-get update
[ ] Install git
sudo apt-get install git
[ ] Install node
# Node version 18.x
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash
sudo apt-get install -y nodejs
[ ] Install PM2
sudo npm install pm2 -g
Ensure you have pm2
installed in your local machine as well.
[ ] Generate and copy SSH key
ssh-keygen
cat ~/.ssh/id_rsa.pub
Add the public key to your git provider.
[ ] Add Git provider to known hosts
ssh -T [email protected]
[ ] Install and setup caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt install caddy
sudo systemctl status caddy
sudo systemctl start caddy
[ ] Setup Caddyfile in local
<domain> {
reverse_proxy localhost:3000
}
[ ] Setup ecosystem.config.cjs in local
module.exports = {
apps: [
{
name: '<instance_name>',
script: './index.js',
node_args: '--experimental-specifier-resolution=node',
instances: 1,
autorestart: true,
exec_mode: 'cluster',
watch: false,
max_memory_restart: '4G',
},
],
deploy: {
production: {
user: 'ubuntu',
host: '52.206.62.160',
ref: 'origin/main',
repo: '<git_remote>',
path: '/home/ubuntu',
'post-deploy': 'npm install && pm2 reload ecosystem.config.cjs && sudo cp ./Caddyfile /etc/caddy/Caddyfile && sudo systemctl reload caddy',
},
},
};
[ ] Setup PM2 ( in local )
pm2 deploy ecosystem.config.cjs production setup
[ ] Copy .env
file to server with port set to 3000 ( or whatever port specified in Caddyfile )
pm2 deploy ecosystem.config.cjs production
[ ] Point domain A record to server public IP address.