Statik bir siteyi barındırmak dünyanın en kolay şeyi. Bir sürü statik html dosyasından oluştuğu için, dosyalarınızı FTP ile yüklemek gibi basit bir yol izleyebilirsiniz. Fakat yaptığınız her değişiklikte, bütün bu dosyaları tek tek bir yerlere yüklemek ölümcül olacaktır.
Bu çileli süreçle uğraşmak istemeyenler için Netlify, Vercel, Cloudflare Pages gibi alternatif platformlar var. Bu platformlar temel olarak şunu yapıyor:
- Siteniz için kullandığınız SSG’ye ait dosyaları barındırdığınız Github reponuzu tanımlıyorsunuz.
- Yaptığınız değişiklikleri, Github reponuza pushladığınız (ittirdiğiniz?) zaman:
- Güncel dosyaları repodan çekiyor.
- Bu dosyaları kullanarak, sitenizi oluşturuyor.
- Yeni sitenizi yayına alıyor.
Bu adımları izleyerek, sitemizi kendi sunucumuza deploy eden bir sistem oluşturabiliriz.
Zero Downtime Deployment
Sitenize ait kaynak kodlarınızı /var/www/site.com/
’da bulundurduğunuzu ve kullandığınız SSG de sitenizi /var/www/site.com/dist/
dizinine oluşturduğunu varsayıyorum. Kullandığınız SSG, sitenizin büyüklüğü ve sunucunuzun donanımına göre bu build adımı bir kaç dakika sürebilir. Bu süreçte dist
dizini içerisinde değişiklikler yapılıyor olduğu için, sitenizdeki bazı sayfalar ya da sitenizin tamamı ziyaretçilere erişilemez durumda olabilir.
Sitenizin oluşturulma ve yayına alınması sürecinde, erişilemez duruma gelmemesine zero downtime deployment deniliyor.
- Sitenizi
/var/www/site.com/builds/current/
dizininden yayınlayacaksınız. - Kullandığınız SSG, buildlerini
/var/www/site.com/builds/dists/
dizinine yeni bir klasör oluşturarak oluşturacak. Yeni dizinin özgün bir isme sahip olabilmesi için, o anki zaman kullanılır; örneğinbuilds/dists/20241108_022248/
. - Build adımı tamamlandıktan sonra yeni buildinizin barındığı
builds/dists/20241108_022248
dizininebuilds/current
dizininden link oluşturacaksınız. Yanibuilds/current
dizini her zaman en güncel buildin bulunduğu dizine işaret eden bir kısayol olacak. - Depolama alanınızın gereksiz şekilde şişmemesi için,
builds/dists
dizinindeki en yeni X adet build harici tüm dizinler silinir.
Sitenizin oluşturulması sürecinde sitenizi ziyaret edenler bir önceki versiyonu görecekler. Siteniz oluşturulduktan sonra yeni versiyonu görmeye başlayacaklar.
Sürecin otomatikleştirilmesi
Bu adımları otomatikleştiren bir script yazdım. Bu scripti /var/www/site.com/deploy.sh
olarak kaydedebilirsiniz. Scriptin .gitignore
da bulunduğuna emin olun.
#!/bin/bash
# Build Directory
BUILDS_DIR="./builds"
ORIGINALS_DIR="dists"
CURRENT_SYMLINK="current"
# Origin'deki değişiklikleri çek
git fetch origin
# Local ile fark var mı kontrol et
if [ "$(git rev-parse HEAD)" != "$(git rev-parse @{u})" ]; then
echo "Origin'de değişiklikler var, güncel dosyalar çekiliyor..."
# Komutları && ile chain haline getir ki adımlardan biri hata verirse devam edilmesin.
git pull origin && \
TIMESTAMP=$(date +"%Y%m%d_%H%M%S") && \
NEW_DIR="$BUILDS_DIR/$ORIGINALS_DIR/$TIMESTAMP" && \
pnpm install && pnpm build --silent --outDir "$NEW_DIR" && \
ln -snf "./$ORIGINALS_DIR/$TIMESTAMP" "$BUILDS_DIR/$CURRENT_SYMLINK"
if [ $? -eq 0 ]; then
# xarg ile başlayan son komut tehlikeli, önceki adımlarda verilen dizinleri siliyor.
# Ne yaptığını bilmiyotsan sakın bulaşma. Eski buildleri elle silebilirsin.
# Eğer son 3 build harici silinsin istiyorsan aşağıdaki satırın başındaki # işaretini kaldır.
# ls -1d $BUILDS_DIR/$ORIGINALS_DIR/* | sort | head -n -3 | xargs -r rm -rf
echo "Başarıyla tamamlandı."
else
echo "Adımların birinde hata oluştu."
fi
else
echo "Origin'de değişiklik yok, iptal."
fi
Script içerisindeki pnpm install && pnpm build --silent --outDir "$NEW_DIR"
kısmı Astro 🡥’ya göre yazıldı. Kullandığınız SSG’ye uygun build komutu yazabilirsiniz.
Peki yaptığınız değişiklikleri Github reponuza pushladıktan sonra, sitenizi barındıran sunucu bu değişikliklerden nasıl haberdar olacak?
Webhook: “Repo Güncellendi”
Webhook, sunucunuzun dışında olan olayların sunucunuza bildirilebilmesi için kullanılan bir teknolojidir. Github reponuza yeni commitlerin pushlanması ya da Telegram kanalınıza yeni mesaj gönderilmesi bu olaylara örnek olarak gösterilebilir.
Github sizin seçebileceğiniz çeşitli olayları belirttiğiniz bir webhook’a gönderebiliyor.
Github webhook tanımlama ekranı
Sunucuya gönderilecek webhook istemlerini alıp işleyebilmek için adnanh/webhook 🡥 uygulamasını kullanıyorum. Bu uygulama varsayılan olarak 9000 portunu dinliyor.
Ubuntu 24.04’te kolayca kurulabiliyor:
$ sudo apt-get install webhook -y
Bu uygulama ayarlarını hooks.json
dosyasını okuyarak yapıyor. Dolayısıyla bir yere geçerli bir hooks.json
oluşturmanız gerekiyor.
$ cd /var/www
$ touch hooks.json
Github’ın gönderdiği push eventlerini kullanmak için gerekli örnek hooks.json
:
[
{
"id": "site-deploy",
"execute-command": "/var/www/site.com/deploy.sh",
"command-working-directory": "/var/www/site.com",
"parse-parameters-as-json": [
{
"source": "payload",
"name": "payload"
}
],
"trigger-rule": {
"and": [
{
"match": {
"type": "payload-hmac-sha1",
"secret": "GITHUB_WEBHOOK_SECRET",
"parameter": {
"source": "header",
"name": "X-Hub-Signature"
}
}
},
{
"match": {
"type": "value",
"value": "refs/heads/master",
"parameter": {
"source": "payload",
"name": "ref"
}
}
}
]
}
}
]
Örnek dosya şu varsayımları yapıyor:
"id": "site-deploy"
: Bu ID, webhookunuzahttp://site.com:9000/hooks/site-deploy
URL’sinden erişilebilir olmasını tanımlıyor.GITHUB_WEBHOOK_SECRET
: Github’da webhook’unuzu tanımlarken oluşturduğunuz gizli tutmanız gereken rasgele ve uzun bir şifre.parse-parameters-as-json
: Github webhook’unuz verileri JSON olarak gönderecek şekilde ayarlandı.refs/heads/master
: Github reponuzdaki ana branch’inizin adımaster
.
Kurduğumuz webhook uygulamasını çalıştırmak için:
$ webhook -port 9000 -hooks /var/www/hooks.json -hotreload -verbose
SSH bağlantınızı kestikten sonra da çalışmasını istiyorsanız:
$ nohup webhook -port 9000 -hooks /var/www/hooks.json -hotreload -verbose &
Not: Sunucunuz yeniden başlatıldığı zaman webhook uygulaması otomatik olarak çalışmayacaktır. Tekrar aynı komutu kullanabilirsiniz.
Sonuç olarak
Yaptığınız değişiklikleri Github reponuza pushladığınız zaman, bir değişiklik olduğunu sunucunuza bildiren bir webhook kullanıyoruz. Bu webhook da sitenizi yeniden oluşturacak deploy.sh
scriptini çalıştırıyor.
Bu sayede hem dosyalarınızı sunucuya elle yüklemekten kurtuluyorsunuz hem de sitenizin oluşturulması sürecinde ziyaretçi kaybı yaşamıyorsunuz.