How to Deploy Automatically on Git Push (Webhook-Based Deployment)

Automating deployment whenever you push to a specific branch removes the manual "SSH in and pull" step, reducing both effort and human error. This guide covers a simple, self-hosted webhook-based deployment setup.

How It Works

  1. You push code to your Git repository
  2. Your Git host sends a webhook notification to your VPS
  3. A small listener on your VPS receives the webhook and runs your deployment script

Prerequisites

  • A VPS with your application already deployed
  • Nginx installed
  • A Git repository hosted somewhere that supports webhooks (GitHub, GitLab, Gitea, etc.)

Step 1 — Install webhook (Lightweight Webhook Listener)

sudo apt install webhook -y

Step 2 — Create a Deployment Script

sudo nano /usr/local/bin/deploy.sh
#!/bin/bash
set -e
cd /var/www/myapp
git pull origin main
npm install --production
pm2 reload myapp
echo "Deployed at $(date)" >> /var/log/deploy.log
sudo chmod +x /usr/local/bin/deploy.sh

Step 3 — Configure the Webhook Definition

sudo nano /etc/webhook.conf
[
  {
    "id": "deploy-myapp",
    "execute-command": "/usr/local/bin/deploy.sh",
    "command-working-directory": "/var/www/myapp",
    "trigger-rule": {
      "match": {
        "type": "value",
        "value": "YOUR_SECRET_TOKEN",
        "parameter": {
          "source": "header",
          "name": "X-Webhook-Token"
        }
      }
    }
  }
]

Step 4 — Start the Webhook Service

sudo systemctl enable --now webhook

Step 5 — Configure Nginx to Proxy the Webhook Endpoint

location /hooks/ {
    proxy_pass http://127.0.0.1:9000;
    proxy_set_header Host $host;
}
sudo nginx -t && sudo systemctl reload nginx

Step 6 — Configure the Webhook in Your Git Host

In your repository's settings (GitHub: Settings → Webhooks → Add webhook), set:

  • Payload URL: https://yourdomain.com/hooks/deploy-myapp
  • Custom header: X-Webhook-Token: YOUR_SECRET_TOKEN (or use the platform's built-in HMAC signature verification if supported, which is more secure than a static token)
  • Trigger: push events to your deployment branch

Step 7 — Test

Push a commit and check:

tail -f /var/log/deploy.log

Improving Security with HMAC Signature Verification

A static token in a header is simpler but less secure than HMAC signature verification (which most Git hosts support) — verifying the payload was genuinely signed by your Git host's secret, rather than just checking a static string that could be intercepted or guessed.

Restricting Which Branch Triggers Deployment

#!/bin/bash
set -e
cd /var/www/myapp
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" != "main" ]; then
    exit 0
fi
git pull origin main
# ... rest of deployment

Common Errors

Webhook received but deployment doesn't run — check webhook service logs:

sudo journalctl -u webhook -n 50

Permission denied during deployment — verify the user running the webhook service has appropriate permissions on the application directory.

Best Practices

  • Use HMAC signature verification over static tokens where your Git host supports it
  • Restrict the webhook endpoint to specific expected source IPs if your Git host publishes them
  • Always run deployment scripts with set -e so failures stop the script rather than continuing silently

Continue Reading

Browse more articles in DevOps & CI/CD.

  • webhook deployment, git push deploy, automated deployment, continuous deployment
  • 0 Los Usuarios han Encontrado Esto Útil
¿Fue útil la respuesta?

Artículos Relacionados

How to Set Up a Self-Hosted GitHub Actions Runner on a VPS

GitHub Actions' hosted runners work well for most projects, but a self-hosted runner on your own...

How to Set Up Blue-Green Deployment on a VPS

Blue-green deployment runs two identical production environments — only one live at a time...

How to Use Ansible for Server Configuration Management

Ansible automates server configuration through simple, human-readable YAML files — letting...

Infrastructure as Code Basics: Managing VPS Config with Terraform

Terraform lets you define infrastructure (VPS instances, networks, DNS records) as code, applied...

How to Build a Simple CI/CD Pipeline with GitHub Actions

GitHub Actions lets you automate testing and deployment directly from your repository, without...