Automatic Deploy with Git

Automate your application deployment: every git push automatically updates the server without manual SSH connections.

02

Method 1: Git bare repository + hook (simple, no external tools)

On server: create the bare repository

bash
# Create the bare repo (receives pushes)
mkdir -p /opt/repos/mysite.git
cd /opt/repos/mysite.git
git init --bare

# Create the post-receive hook
nano hooks/post-receive
bash
#!/bin/bash
# /opt/repos/mysite.git/hooks/post-receive

TARGET="/var/www/mysite"
GIT_DIR="/opt/repos/mysite.git"
BRANCH="main"

while read oldrev newrev ref; do
    BRANCH_NAME=$(echo $ref | cut -d/ -f3)
    if [ "$BRANCH_NAME" = "$BRANCH" ]; then
        echo "--- Deploying branch $BRANCH ---"
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH

        # Post-deploy commands (adapt to your stack)
        cd $TARGET

        # Node.js
        # npm install --production
        # pm2 restart mysite

        # PHP/Composer
        # composer install --no-dev --optimize-autoloader

        # Python
        # pip install -r requirements.txt
        # systemctl restart gunicorn-mysite

        echo "--- Deploy completed ---"
    fi
done
bash
chmod +x /opt/repos/mysite.git/hooks/post-receive
mkdir -p /var/www/mysite

On local PC: add the remote

bash
# Add the server as "production" remote
git remote add production ssh://root@185.100.xxx.xxx/opt/repos/mysite.git

# Deploy: push to the server
git push production main
03

Method 2: GitHub/GitLab Webhook (recommended for teams)

Install a webhook server

bash
# With webhook (lightweight Go tool)
sudo apt install webhook -y

# Or install from GitHub
wget https://github.com/adnanh/webhook/releases/latest/download/webhook-linux-amd64.tar.gz
tar -xzf webhook-linux-amd64.tar.gz
sudo mv webhook-linux-amd64/webhook /usr/local/bin/

Create the deploy script

bash
sudo nano /opt/deploy/deploy-mysite.sh
bash
#!/bin/bash
cd /var/www/mysite
git pull origin main
npm install --production
pm2 restart mysite
echo "Deploy completed: $(date)"
bash
chmod +x /opt/deploy/deploy-mysite.sh

Configure webhooks

bash
sudo nano /etc/webhook/hooks.json
json
[
  {
    "id": "deploy-mysite",
    "execute-command": "/opt/deploy/deploy-mysite.sh",
    "command-working-directory": "/var/www/mysite",
    "pass-arguments-to-command": [],
    "trigger-rule": {
      "match": {
        "type": "payload-hmac-sha256",
        "secret": "shared-secret-with-github",
        "parameter": {
          "source": "header",
          "name": "X-Hub-Signature-256"
        }
      }
    }
  }
]
bash
# Start webhook on port 9000
webhook -hooks /etc/webhook/hooks.json -port 9000 -verbose &

# Or as a systemd service
sudo nano /etc/systemd/system/webhook.service
ini
[Unit]
Description=Webhook Deploy Service
After=network.target

[Service]
ExecStart=/usr/local/bin/webhook -hooks /etc/webhook/hooks.json -port 9000
Restart=always
User=www-data

[Install]
WantedBy=multi-user.target
bash
sudo systemctl enable webhook && sudo systemctl start webhook

Configure GitHub

  • Go to repository GitHub → Settings → Webhooks → Add webhook
  • Payload URL: http://your-server:9000/hooks/deploy-mysite
  • Content type: application/json
  • Secret: the same shared-secret-with-github
  • Event: Just the push event
04

Method 3: GitHub Actions with SSH

yaml
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/mysite
            git pull origin main
            npm install --production
            pm2 restart mysite

In GitHub Secrets add:

  • SERVER_HOST: server IP
  • SERVER_USER: SSH user (e.g. root)
  • SSH_PRIVATE_KEY: content of ~/.ssh/id_rsa (private key)
05

Method 4: rsync + CI (for static files)

yaml
# GitHub Actions: deploy static site
  run: npm run build

  uses: burnett01/rsync-deployments@6.0.0
  with:
    switches: -avzr --delete
    path: dist/
    remote_path: /var/www/mysite/
    remote_host: ${{ secrets.SERVER_HOST }}
    remote_user: root
    remote_key: ${{ secrets.SSH_PRIVATE_KEY }}
  • name: Build
  • name: Deploy with rsync
06

Zero-downtime deploy with PM2

bash
# Instead of pm2 restart (causes brief downtime):
pm2 reload mysite --update-env
07

Quick rollback

With the git bare method:

bash
# On server: return to previous commit
cd /var/www/mysite
git log --oneline -5
git checkout <old-commit-hash> .
pm2 restart mysite

DeluxHost, gegründet 2023, bietet hochwertige Hosting-Lösungen für verschiedene digitale Anforderungen. Wir bieten Shared Hosting, VPS und dedizierte Server mit erweiterter Sicherheit und globalen Rechenzentren.

© DeluxHost, Alle Rechte vorbehalten. | USt-IdNr.: IT17734661006
Alle Systeme betriebsbereit