Git Hooks ile otomatik deployment: basit ve güvenli kurulum
Git hooks ile push sonrası otomatik deployment yapmayı; güvenlik, yetkilendirme, hata yakalama ve pratik örneklerle adım adım öğrenin.
Git ile çalışan ekiplerde en sık yaşanan sorun, kodu branch’e itmekle canlıya almayı aynı disiplin içinde bağlayamamak. Manuel deploy hem zaman kaybettirir hem de “şu komutu çalıştırmayı unuttum” hatalarını artırır. Git hooks (server-side veya local) kullanarak push anında otomatik deployment akışı kurmak, süreci standardize eder. Bu rehberde, basit bir kurulumla push sonrası otomatik yayın yapmayı; log, yetkilendirme ve güvenlik noktalarını net şekilde göreceksiniz.
Aşağıdaki kurulum “basit ama doğru” hedefindedir: Hook çalışır, sadece belirli branch’ler publish edilir, deployment bir script üzerinden yürür, hatalar log’a yazılır ve yetkiler kontrollü olur.
Git Hooks ile deployment nasıl çalışır?
Git hook’lar, Git komutları çalışırken tetiklenen script’lerdir. Deployment için en pratik seçenekler:
- Server-side hook (önerilir): Kod repository’ye push edildiğinde sunucuda tetiklenir.
- Client-side hook: Push öncesi/sonrası local makinede çalışır, ancak dağıtım sunucu tarafında yapılacağı için tipik olarak daha karmaşık yetkilendirme ister.
Deployment için “push gelince yayınla” mantığı en doğal olarak server-side hook’ta kurulur.
Neden server-side hook?
- Yetkilendirme tek yerde yönetilir: Deployment, sunucudaki kontrollü kullanıcıyla çalışır.
- Her push’ta çalışacak akış tek bir noktada standartlaşır.
- CI/CD gibi ağırlaşmadan, küçük ekiplerin “doğrudan üretime al” ihtiyacını karşılar.
Not: Production’a doğrudan deploy her ekipte doğru değildir. Kritik sistemlerde staging ve onay adımı tercih edilir. Bu rehber yine de staging mantığını da kolay eklemeye uygun yazıldı.
Hedef senaryo ve gereksinimler
Bu rehberde şu senaryoyu kuracağız:
- Deployment yapılacak bir Linux sunucunuz var.
- Uygulama kodu, sunucuda çıplak (bare) bir Git repository’ye push ediliyor.
- Push sonrası sunucuda
post-receivehook tetikleniyor. - Hook, sadece doğru branch’i kontrol ediyor ve deployment script’ini çağırıyor.
- Deployment script’i kodu check-out ediyor ve uygulamayı yeniden başlatıyor.
Gerekli paketler
Sunucu tarafında şunlar genelde yeterlidir:
- git
- Uygulamanın deploy yöntemi (ör. npm, pip, composer, systemctl vb.)
Örnek ortam
- Web uygulaması: Node.js veya benzeri (yeniden başlatma için
systemctlkullanacağız) - Deployment dizini:
/var/www/app - Bare repo:
/srv/git/app.git
Kurulum adım adım (bare repo + post-receive)
Aşağıdaki adımlar, hook ile “push → otomatik deploy” akışını kurar.
1) Bare repository oluşturun
Sunucuda bare repo oluşturun:
sudo mkdir -p /srv/git
sudo git init --bare /srv/git/app.git
sudo chown -R $USER:$USER /srv/git/app.git
Bare repo, yalnızca push almak için kullanılır. Deployment için ayrıca bir çalışma dizini (working tree) tutacağız.
2) Uzak repo erişimini hazırlayın
Makinenizden sunucuya push atmak için URL formatı genelde SSH’dir:
- Local kullanıcı sunucuda SSH ile erişebilmeli
- Sunucuda ilgili repo için yazma izni olmalı
En sade akış: - Localde repo’yu sunucuya ekleyin:
git remote add production ssh://kullanici@sunucu-ip/srv/git/app.git
- Branch’i push edin:
git push production main
3) deployment script’i yazın
Hook’un işi çağırmaktan ibaret olmalı; “işin kendisini” ayrı script yapsın. Böylece test etmek ve loglamak kolaylaşır.
Örnek deployment script’i:
- Dosya:
/usr/local/bin/deploy-app.sh - İçerik:
#!/usr/bin/env bash
set -euo pipefail
BRANCH_NAME="${1:-main}"
APP_DIR="/var/www/app"
REPO_DIR="/srv/git/app.git"
SERVICE_NAME="app.service"
echo "[deploy] Starting deploy for branch: ${BRANCH_NAME} at $(date -Is)"
# Çalışma dizini yoksa oluştur
if [ ! -d "$APP_DIR" ]; then
mkdir -p "$APP_DIR"
fi
# Çalışma dizinini güncellemek için bir yöntem seçin.
# Basit yöntem: çalışma dizininde git init + remote + fetch + checkout
if [ ! -d "$APP_DIR/.git" ]; then
git init "$APP_DIR" >/dev/null
git -C "$APP_DIR" remote add origin "$REPO_DIR"
fi
git -C "$APP_DIR" fetch --prune origin "$BRANCH_NAME"
git -C "$APP_DIR" checkout -f "$BRANCH_NAME"
# Uygulama komutları (örnek: Node.js)
# npm ci
# npm run build
# pm2 restart veya systemd restart
sudo systemctl restart "$SERVICE_NAME"
echo "[deploy] Done at $(date -Is)"
Script’i çalıştırılabilir yapın:
sudo chmod +x /usr/local/bin/deploy-app.sh
4) Hook script’ini ekleyin (post-receive)
Bare repo’nun hook klasörü:
/srv/git/app.git/hooks/post-receive
Örnek içerik (branch kontrolü + log):
#!/usr/bin/env bash
set -euo pipefail
# post-receive stdin: eski_sha yeni_sha ref
# Örnek: <old> <new> refs/heads/main
LOG_FILE="/var/log/git-deploy-app.log"
while read -r oldrev newrev refname; do
echo "[hook] Updated ref: $refname ($oldrev -> $newrev) at $(date -Is)" >> "$LOG_FILE"
# Sadece main branch
if [ "$refname" = "refs/heads/main" ]; then
echo "[hook] Deploy triggered for $refname" >> "$LOG_FILE"
/usr/local/bin/deploy-app.sh main >> "$LOG_FILE" 2>&1
else
echo "[hook] Ignored $refname" >> "$LOG_FILE"
fi
done
Hook’u çalıştırılabilir yapın:
sudo tee /srv/git/app.git/hooks/post-receive >/dev/null <<'EOF'
# (içeriği buraya yapıştırın)
EOF
sudo chmod +x /srv/git/app.git/hooks/post-receive
post-receive, push tamamlandıktan sonra çalışır. Bu yüzden “kodu aldım mı?” problemi büyük ölçüde çözülür.
5) İlk test
- Localde
mainbranch’ini güncelleyin. - Sunucuya push edin.
/var/log/git-deploy-app.logdosyasını kontrol edin.
Örnek komut:
tail -n 200 /var/log/git-deploy-app.log
Beklenen: - hook log satırları - deployment script log satırları - servis restart sonrası “Done” satırı
Güvenlik: yetkilendirme ve yetki sınırları
Otomatik deploy doğru kurulmazsa, “her push otomatik canlıya gitsin” tehlikesi doğurur. Güvenliği özellikle şu başlıklarda ele alın.
1) Hook kullanıcı yetkisi
Hook’u çalıştıran Git süreci, bare repo’nun bulunduğu sistemdeki yetkilerle çalışır. Deployment script’inde sudo systemctl restart kullanımı varsa:
- sudoers dosyasında sadece servis restart yetkisi verin
- tüm komutlar için tam yetki vermeyin
Basit hedef:
- sadece systemctl restart app.service izni
2) Sadece belirli branch’lere deploy
Hook’ta refs/heads/main dışında her şeyi ignore edin. Bu, istemsiz feature branch deploy’unu engeller.
3) Repository içeriği doğrulaması
Pratikte şu iki kontrol kritik olur: - Deploy edilecek branch’in doğru upstream’ten geldiğinden emin olun (repo URL ve erişim kontrolü) - Gerekirse commit imzası (GPG) doğrulaması ekleyin
Özellikle ekip büyüdükçe commit standardı (ör. GPG imzalı) otomatik deployment için güven katmanı olur.
4) Logları saklayın
Hook ve deploy hataları görünmezse sorun çözmek zorlaşır. Log dosyasını şunlar için kullanın: - hook tetikleniyor mu? - hangi branch geldi? - script hatası nerede çıktı?
Hata yönetimi ve kararlı deployment
Otomatik süreçte asıl değer, hatanın sessiz kalmamasıdır. Hook tarafında set -euo pipefail kullandık; fakat bir hook failure’ında Git işlemi genellikle push tarafında da bir hata hisseder.
1) Deployment kilidi (eşzamanlılık problemi)
Arka arkaya iki push gelirse, iki deployment aynı anda koşabilir. Bunu engellemek için bir lock kullanın.
Örnek (deploy script içine eklenebilir):
LOCK_FILE="/tmp/deploy-app.lock"
exec 9>"$LOCK_FILE"
flock -n 9 || { echo "[deploy] Another deploy is running"; exit 1; }
Bu şekilde ikinci deploy, birincisi bitmeden başlatılmaz.
2) Atomic yayın (varsa symlink yöntemi)
Uygulamanın yayınlanması “yarım kontrol” durumda kalıyorsa kullanıcılar hatalı sayfa görebilir. Basit bir iyileştirme: - Yeni sürümü ayrı dizine al - Trafiği symlink ile değiştir - Restart sonrası symlink’i geç
Bu rehberde servis restart yöntemi gösterdik. Eğer mümkünse “blue/green” benzeri bir yaklaşım, TTFB ve kullanıcı etkisini daha stabil hale getirir.
3) Build adımını hangi noktada yapmalısınız?
- Kod yalnızca checkout ile güncelleniyorsa: build adımı deployment script’inde çalışır.
- Build çok uzun sürüyorsa: build’i ayrı sistemde yapmak (CI) daha doğru olur.
Git hooks ile doğrudan deploy pratik olsa da, ağır build süreçleri sunucu yükünü artırır.
Branch stratejisi: main yerine staging ile net akış
Tek branch’e deploy bazen yetersiz kalır. Şu iki aşamalı yaklaşım, hook’un faydasını korur:
main→ staging sunucusurelease/*veyatag→ production
Bu stratejiyi hook’ta branch/tag kontrolü ile netleştirin.
Tag ile deployment (örnek mantık)
- Üretime alım:
refs/tags/v*şeklinde tag geldiğinde çalıştırın. - Build sürümü tag olduğu için geriye dönüş (rollback) daha kolay olur.
Net kontrol listesi (kurulumu tamamlamadan önce)
Aşağıdaki maddeler çalışmıyorsa “otomatik deploy var ama güvenilir değil” olur.
- [ ]
post-receivehook çalışıyor (log’a yazıyor) - [ ] Sadece hedef branch (ör.
refs/heads/main) deploy tetikleniyor - [ ] Deployment script’i çalıştırılabilir ve doğru kullanıcıyla işlem yapıyor
- [ ] Log dosyası oluşturuluyor ve hatalar
stderrile yakalanıyor - [ ] Eşzamanlı push’ta iki deploy aynı anda koşmuyor (lock var)
- [ ] Servis restart komutu çalışıyor (
systemctl status app.servicedoğrulanır)
İyileştirme seçenekleri: hook + servis standardı
Bu rehberde “tek sunucuda” basit kurulum yaptık. NetKıyas okuyucularının sık talebi olan bazı geliştirmeler:
- Önce staging sonra production: Test edilen sürümün production’a alınması.
- Sürümleme disiplini: Tag ile deploy, rollback kolaylığı.
- Servis standardı:
systemdunit dosyaları ile restart, log ve health kontrolü. - Rate/timeout kontrolü: Uzun süren deploy’larda script içinde timeout ekleme.
Sonuç: ilk kurulumda en doğru aksiyon
Hemen bugün yapabileceğiniz net aksiyon şudur: Bare repo + post-receive ile branch kontrollü otomatik deployment kurun; deployment işini ayrı bir script’e alın; her çalışmada log üretin ve eşzamanlı deploy için lock ekleyin. Bu üç yapı taşını tamamladıktan sonra staging/tag gibi bir sonraki adımı ekleyin. Böylece “push yaptım ve canlı otomatik güncellendi” beklentisi hem teknik olarak çalışır hem de operasyonel olarak yönetilebilir kalır.
Hosting karşılaştırması yapmaya hazır mısın?
100+ firmanın fiyatlarını tek tıkla karşılaştır, en uygun paketi bul.
Hosting Karşılaştır →İlgili Yazılar
Crypto Miner için Sunucu: Yasal ve Etik Sınırlar Rehberi (2026)
Crypto miner için sunucu kurarken yasal sorumluluk ve etik riskleri; sağlayıcı sözleşmeleri, izin süreçleri, izleme ve kaynak planlama ile netleştirin.
Raspberry Pi ile self-hosting gerçekçi mi? Maliyet & performans
Raspberry Pi ile self-hosting yapmak hangi senaryolarda gerçekçi, hangi senaryolarda riskli? Maliyet, performans ve güvenlik kontrol listesi.
Lazy Loading sunucu tarafında nasıl etki eder? Performans rehberi
Lazy loading (tembel yükleme) genelde tarayıcıda görünürlükle çalışır. Bu rehberde sunucu tarafına etkisini, ölçüm metriklerini ve net kontrolleri anlatıyoruz.
Ücretsiz Web Sitesi Virüs Tarama Araçları: Net Rehber
Web sitenizde zararlı kod var mı? Ücretsiz tarama araçlarıyla URL, dosya ve DNS kaynaklı riskleri adım adım tespit edin.
