Tue Aug 05 2025
/!\ When you clone your applications on the VPS, make sure they are setup to run on different ports
First make sure that pm2 is installed with:
pm2 -v
If not install with:
sudo npm install -g pm2
Now navigate to your application's directory and assuming your app name is "my-app" run:
pm2 start index.js --name my-app
Or if using npm start:
pm2 start npm --name my-app -- start
You can check the list of running apps with:
pm2 list
Now to make the applications list consistent across machine restarts run (If you didn't do it before):
pm2 startup
And copy/paste the displayed command onto the terminal Lastly to save the current list of processes run:
pm2 save
More information on PM2 here: PM2 Docs
Check nginx installation:
sudo systemctl status nginx
If its not installed, run:
sudo apt update
sudo apt install nginx
Add a config file to /etc/nginx/sites-available with the name of your app:
sudo vim /etc/nginx/sites-available/myapp
Paste this:
server {
listen 80;
server_name mydomain.com www.mydomain.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Enable the site by symlinking the config file to /etc/nginx/sites-enabled/ Make sure that you use absolute paths:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-ebabled/
Check for syntax errors with:
sudo nginx -t
If it's okay, reload nginx:
sudo systemctl reload nginx
At this point you can already point your domain to your VPS with an A record, if your security rules allows it...
Check certbot installation:
certbot --version
Check certbot nginx plugin installation:
certbot plugins
If not already installed, install certbot and the nginx plugin with:
sudo apt install certbot python3-certbot-nginx
Run certbot to generate a certificate for your app:
sudo certbot --nginx -d mydomain.com -d www.mydomain.com
That will automatically modify the config files in /etc/nginx/sites-enabled and /etc/nginx/sites-available
And you should be live!
If it doesn't directly work, try reloading nginx:
sudo systemctl reload nginx
First go on your github reposiroty in Settings>Secrets and variables>Actions and add three repository secrets:
Then in the Actions tab add a new workflow with this:
name: Deploy to VPS
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -p ${{ secrets.VPS_PORT || 22 }} ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to VPS
run: |
ssh -p ${{ secrets.VPS_PORT || 22 }} ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} << 'EOF'
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
cd /path/to/myapp
git pull origin main
npm install
pm2 restart myappname
EOF
Commit the changes and it should deploy when you push to the main branch.
That's all.
- Mafupa