Linux

Automatic Node.js deployment with GitHub webhooks

By ColossusCloud's Team January 22, 2026

What we’re building

When pushing code to GitHub, VPS automatically:

  1. Receives notification from GitHub
  2. Pulls latest code
  3. Installs dependencies
  4. Restarts application

This is webhook-based deployment. GitHub sends HTTP requests to servers whenever pushing, and servers run scripts to update themselves.

Prerequisites

Before starting:

Step 1: Install webhook listener

We’ll use lightweight webhook tool to listen for GitHub notifications.

On Ubuntu:

sudo apt update
sudo apt install -y webhook

Step 2: Create deployment script

Create a script running whenever GitHub sends webhooks. This pulls code and restarts apps.

sudo mkdir -p /opt/scripts
sudo nano /opt/scripts/deploy.sh

Add the following (adjust paths):

#!/bin/bash

# Configuration
REPO_DIR="/home/youruser/your-app"
BRANCH="main"
LOG_FILE="/var/log/deploy.log"

echo "=== Deployment started at $(date) ===" >> $LOG_FILE

cd $REPO_DIR

# Pull latest changes
git fetch origin
git reset --hard origin/$BRANCH

# Install dependencies
npm install >> $LOG_FILE 2>&1

# Build if needed (uncomment if you have a build step)
# npm run build >> $LOG_FILE 2>&1

# Restart the application with PM2
pm2 restart your-app-name >> $LOG_FILE 2>&1

echo "=== Deployment completed at $(date) ===" >> $LOG_FILE

Make it executable:

sudo chmod +x /opt/scripts/deploy.sh

Step 3: Configure webhook listener

Create configuration file:

sudo mkdir -p /etc/webhook
sudo nano /etc/webhook/hooks.json

Add configuration:

[
  {
    "id": "deploy",
    "execute-command": "/opt/scripts/deploy.sh",
    "command-working-directory": "/opt/scripts",
    "response-message": "Deployment triggered",
    "trigger-rule": {
      "and": [
        {
          "match": {
            "type": "payload-hmac-sha256",
            "secret": "your-secret-here",
            "parameter": {
              "source": "header",
              "name": "X-Hub-Signature-256"
            }
          }
        },
        {
          "match": {
            "type": "value",
            "value": "refs/heads/main",
            "parameter": {
              "source": "payload",
              "name": "ref"
            }
          }
        }
      ]
    }
  }
]

Important: Replace your-secret-here with a random string. Generate one with:

openssl rand -hex 32

Step 4: Create systemd service

sudo nano /etc/systemd/system/webhook.service

Add:

[Unit]
Description=Webhook listener
After=network.target

[Service]
ExecStart=/usr/bin/webhook \
  -hooks /etc/webhook/hooks.json \
  -port 9000 \
  -verbose
Restart=always
User=root

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable webhook
sudo systemctl start webhook

Step 5: Open webhook port

In ColossusCloud control panel, add firewall rule allowing port 9000 (or chosen port).

Step 6: Configure GitHub

  1. Go to repository on GitHub
  2. Click SettingsWebhooksAdd webhook
  3. Configure:
    • Payload URL: http://your-server-ip:9000/hooks/deploy
    • Content type: application/json
    • Secret: Same secret from hooks.json
    • Events: Select “Just the push event”
  4. Click Add webhook

Step 7: Test deployment

Make a small change and push:

git add .
git commit -m "Test automatic deployment"
git push origin main

Check server logs:

tail -f /var/log/deploy.log

Explore VPS plans for reliable deployment servers.