What we’re building
When pushing code to GitHub, VPS automatically:
- Receives notification from GitHub
- Pulls latest code
- Installs dependencies
- 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:
- A VPS with Node.js installed
- Application deployed and running with PM2
- SSH access to server
- GitHub repository with code
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
- Go to repository on GitHub
- Click Settings → Webhooks → Add webhook
- 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”
- Payload URL:
- 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.