Git ile Otomatik Deploy: Webhook ile Sunucuya Push
Git push işlemiyle kodunuzu otomatik sunucuya deploy edin. GitHub webhook, bare git repo ve post-receive hook ile CI/CD pipeline kurulum rehberi.
Otomatik Deploy Nedir ve Neden Önemlidir?
Otomatik deploy (Continuous Deployment - CD), kod değişikliklerinin Git'e push edildiğinde otomatik olarak sunucuya yansıtılması sürecidir. Manuel FTP/SFTP ile dosya aktarımı yerine; git push → webhook tetikleme → sunucu güncelleme şeklinde çalışan bu sistem, geliştirme sürecini büyük ölçüde hızlandırır ve hata riskini azaltır.
Bu makalede iki farklı yöntem ele alacağız:
- Yöntem 1: Bare Git Repository ile doğrudan push
- Yöntem 2: GitHub/GitLab Webhook ile otomatik deploy
Yöntem 1: Bare Git Repository ile Deploy
1. Sunucuda Bare Repository Oluşturma
# Sunucuda deploy kullanıcısı oluştur
sudo adduser deployer
sudo usermod -aG www-data deployer
# Bare repository oluştur
sudo mkdir -p /var/repo/myapp.git
cd /var/repo/myapp.git
sudo git init --bare
# Web root dizini oluştur
sudo mkdir -p /var/www/myapp
sudo chown deployer:www-data /var/www/myapp
2. post-receive Hook Oluşturma
sudo nano /var/repo/myapp.git/hooks/post-receive
#!/bin/bash
set -e
TARGET="/var/www/myapp"
GIT_DIR="/var/repo/myapp.git"
BRANCH="main"
while read oldrev newrev ref; do
BRANCH_NAME="${ref#refs/heads/}"
if [ "$BRANCH_NAME" = "$BRANCH" ]; then
echo ">>> Deploy başlıyor: $BRANCH dalı"
# Kodu web dizinine çıkart
git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
echo ">>> Bağımlılıklar yükleniyor..."
cd "$TARGET"
# PHP (Composer) için
if [ -f "composer.json" ]; then
composer install --no-dev --optimize-autoloader --quiet
fi
# Node.js için
if [ -f "package.json" ]; then
npm ci --production
npm run build
fi
# Laravel için
if [ -f "artisan" ]; then
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
fi
echo ">>> Deploy tamamlandı!"
fi
done
sudo chmod +x /var/repo/myapp.git/hooks/post-receive
sudo chown deployer:deployer /var/repo/myapp.git/hooks/post-receive
3. SSH Anahtarını Ayarlama
# Yerel makinenizde
cat ~/.ssh/id_ed25519.pub
# Sunucuda (deployer kullanıcısı olarak)
sudo mkdir -p /home/deployer/.ssh
sudo nano /home/deployer/.ssh/authorized_keys
# Public key'i yapıştırın
sudo chmod 700 /home/deployer/.ssh
sudo chmod 600 /home/deployer/.ssh/authorized_keys
sudo chown -R deployer:deployer /home/deployer/.ssh
4. Yerel Projeye Remote Ekle ve Push Et
# Yerel projenizde
git remote add production deployer@SUNUCU_IP:/var/repo/myapp.git
# İlk push
git push production main
# Sonraki deploylar için
git add .
git commit -m "Yeni özellik eklendi"
git push production main
Yöntem 2: GitHub Webhook ile Otomatik Deploy
Bu yöntemde GitHub'a push edildiğinde GitHub, sunucunuzdaki bir webhook endpoint'ini çağırır. Sunucu bu çağrıyı alınca deploy scriptini çalıştırır.
1. Deploy Script Oluşturma
sudo nano /var/www/myapp/deploy.sh
#!/bin/bash
set -e
APP_DIR="/var/www/myapp"
BRANCH="main"
LOG_FILE="/var/log/deploy.log"
echo "[$(date)] Deploy başladı" >> "$LOG_FILE"
cd "$APP_DIR"
# Güncel kodu çek
git fetch origin
git reset --hard "origin/$BRANCH"
# Bağımlılıkları güncelle
if [ -f "composer.json" ]; then
composer install --no-dev --optimize-autoloader 2>&1 >> "$LOG_FILE"
fi
# Laravel cache yenile
if [ -f "artisan" ]; then
php artisan config:cache 2>&1 >> "$LOG_FILE"
php artisan route:cache 2>&1 >> "$LOG_FILE"
php artisan migrate --force 2>&1 >> "$LOG_FILE"
fi
# Web sunucusunu yeniden başlat
sudo systemctl reload nginx
echo "[$(date)] Deploy tamamlandı" >> "$LOG_FILE"
sudo chmod +x /var/www/myapp/deploy.sh
2. PHP Webhook Handler
sudo nano /var/www/webhook/deploy.php
<?php
define('SECRET', 'GIZLI_WEBHOOK_SIRRINIZ');
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $payload, SECRET);
if (!hash_equals($expected, $signature)) {
http_response_code(403);
die('Forbidden: Invalid signature');
}
$data = json_decode($payload, true);
if (($data['ref'] ?? '') === 'refs/heads/main') {
$output = shell_exec('/var/www/myapp/deploy.sh 2>&1');
file_put_contents('/var/log/deploy.log', $output, FILE_APPEND);
echo 'Deploy tetiklendi';
} else {
echo 'Farklı dal, deploy atlandı';
}
3. Nginx Webhook Endpoint Yapılandırması
server {
listen 443 ssl http2;
server_name webhook.example.com;
location /deploy {
root /var/www/webhook;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/deploy.php;
include fastcgi_params;
}
}
4. GitHub'da Webhook Tanımlama
- GitHub → Repo → Settings → Webhooks → Add webhook
- Payload URL:
https://webhook.example.com/deploy - Content type:
application/json - Secret: GIZLI_WEBHOOK_SIRRINIZ
- Events: "Just the push event"
- Save
sudo Yetkilerini Güvenli Yapılandırma
sudo visudo -f /etc/sudoers.d/deploy
# www-data kullanıcısına yalnızca nginx reload için sudo
www-data ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx
GitLab CI/CD Alternatifi
# .gitlab-ci.yml
stages:
- deploy
deploy_production:
stage: deploy
only:
- main
script:
- ssh deployer@$SUNUCU_IP "/var/www/myapp/deploy.sh"
environment:
name: production
Güvenlik Önerileri
- Webhook secret'ınızı güçlü ve rastgele tutun:
openssl rand -hex 32 - Deploy scriptine yalnızca gerekli izinleri verin
- Webhook endpoint IP'sini GitHub/GitLab IP aralıklarıyla kısıtlayın
- Deploy loglarını düzenli inceleyin
- HTTPS zorunlu tutun (HTTP üzerinden webhook çalıştırmayın)
Özet
Git ile otomatik deploy iki temel yöntemle sağlanabilir: Bare repository ve post-receive hook yöntemi basit ve sunucu bağımlılığı az bir çözümdür. Webhook yöntemi ise GitHub/GitLab entegrasyonu sayesinde daha güçlü CI/CD pipeline'larına kapı açar. Her iki yöntemde de güvenlik için secret doğrulama ve HTTPS zorunludur.
Yorumlar
Henüz yorum yok. İlk yorumu siz yapın!