Blog’a Dön

Git ile Sunucuya Deploy: Otomatik Yayınlama Rehberi

Git ile sunucuya deploy nasıl yapılır? Deploy anahtarı, yayınlama betiği, GitHub Actions ile otomatik deploy, ayrı kullanıcı, gizli bilgiler ve geri alma.

Nodesty Ekibi4 dk okumaSunucular
Koyu Nodesty arka planında Git Deploy yazısı ile SSH, Actions ve Rollback ifadeleri

Git ile deploy, uygulamanızın kodunu sunucuya FTP ile elle yüklemek yerine bir Git deposundan çekerek yayınlamaktır. En basit hâliyle sunucuda git pull çalıştırıp uygulamayı yeniden başlatırsınız; bir adım ileride ise kodu ana dala gönderdiğiniz anda GitHub Actions gibi bir araç bunu sizin yerinize yapar. Her yayın bir commit'e karşılık geldiği için sunucuda neyin çalıştığını her zaman bilir, bir sorun çıktığında saniyeler içinde geri dönersiniz.

Bu rehberde sunucuya deploy anahtarı eklemeyi, bir yayınlama betiği yazmayı, GitHub Actions ile otomatik deploy kurmayı, güvenlik önlemlerini ve geri almayı anlatıyoruz.

Neden Git ile deploy?

  • Tekrarlanabilirlik: Her yayın aynı adımlarla yapılır; "bu sefer şu dosyayı unuttum" sorunu ortadan kalkar.
  • İzlenebilirlik: Sunucuda hangi commit'in çalıştığını git log -1 ile görürsünüz.
  • Kolay geri alma: Hatalı bir yayından önceki sürüme tek komutla dönersiniz.
  • Ekip çalışması: Herkes kodu depoya gönderir; sunucuya yalnızca deploy süreci dokunur.

1. Adım: Ayrı bir deploy kullanıcısı

Uygulamayı ve deploy sürecini root yerine ayrı bir kullanıcıyla çalıştırın. Sunucunuza SSH ile bağlandıktan sonra:

sudo adduser deploy
sudo mkdir -p /var/www/proje
sudo chown deploy:deploy /var/www/proje
sudo su - deploy

2. Adım: Deploy anahtarı

Sunucunun depodan kod çekebilmesi için yalnızca o depoya erişebilen bir deploy anahtarı oluşturun:

ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -N "" -C "deploy@sunucu"
cat ~/.ssh/deploy_key.pub

Açık anahtarı GitHub'da deponun Settings → Deploy keys → Add deploy key bölümüne ekleyin ve yazma iznini kapalı bırakın. Ardından SSH'a bu anahtarı GitHub için kullanmasını söyleyin; ~/.ssh/config dosyasına ekleyin:

Host github.com
    IdentityFile ~/.ssh/deploy_key
    IdentitiesOnly yes

Depoyu sunucuya klonlayın:

git clone git@github.com:kullanici/proje.git /var/www/proje

Deploy anahtarı yalnızca tek bir depoyu okuyabildiği için sunucu ele geçirilse bile saldırgan diğer depolarınıza ve hesabınıza ulaşamaz.

3. Adım: Yayınlama betiği

Her yayında çalışacak adımları bir betikte toplayın, örneğin /home/deploy/deploy.sh. Bir Node.js uygulaması için:

#!/bin/bash
set -euo pipefail

cd /var/www/proje
git fetch origin
git reset --hard origin/main

npm ci
npm run build

pm2 reload proje
echo "Yayınlandı: $(git log -1 --oneline)"
  • set -euo pipefail: Herhangi bir adım başarısız olursa betik durur; yarım kalmış bir derleme yayına alınmaz.
  • git reset --hard origin/main: Sunucudaki kodu deponun ana dalıyla birebir eşitler. Sunucuda elle yapılan değişiklikler silinir; kodu yalnızca depo üzerinden değiştirme alışkanlığı bu yüzden önemlidir.
  • npm ci: package-lock.json dosyasındaki sürümleri birebir kurar.
  • pm2 reload: Uygulamayı kesintisiz yeniden başlatır. pm2 ve systemd ile uygulama çalıştırmayı Discord botu 7/24 aktif tutma rehberimizde anlattık.

PHP projelerinde npm satırlarının yerine composer install --no-dev --optimize-autoloader, Laravel'de ek olarak php artisan migrate --force ve önbellek komutları gelir. Betiği çalıştırılabilir yapın:

chmod +x ~/deploy.sh

Artık bir yayın için sunucuda ~/deploy.sh çalıştırmanız yeterlidir.

4. Adım: GitHub Actions ile otomatik deploy

Bir adım ileri giderek ana dala her gönderimde betiğin kendiliğinden çalışmasını sağlayabilirsiniz.

  1. Actions için ayrı bir SSH anahtarı oluşturun (kendi bilgisayarınızda):
    ssh-keygen -t ed25519 -f actions_key -N "" -C "github-actions"
    

    actions_key.pub içeriğini sunucuda deploy kullanıcısının ~/.ssh/authorized_keys dosyasına ekleyin.
  2. GitHub'da gizli değişkenleri tanımlayın. Deponun Settings → Secrets and variables → Actions bölümüne DEPLOY_SSH_KEY (actions_key dosyasının içeriği) ve SERVER_HOST (sunucunuzun IP adresi) ekleyin.
  3. İş akışı dosyasını oluşturun: .github/workflows/deploy.yml
    name: Deploy
    on:
        push:
            branches: [main]
    
    jobs:
        deploy:
            runs-on: ubuntu-latest
            steps:
                - name: Sunucuya yayınla
                  env:
                      SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
                      HOST: ${{ secrets.SERVER_HOST }}
                  run: |
                      mkdir -p ~/.ssh
                      echo "$SSH_KEY" > ~/.ssh/id_ed25519
                      chmod 600 ~/.ssh/id_ed25519
                      ssh-keyscan -H "$HOST" >> ~/.ssh/known_hosts
                      ssh deploy@"$HOST" '~/deploy.sh'
    

Bundan sonra main dalına her gönderimde GitHub, sunucunuza bağlanıp yayınlama betiğini çalıştırır. Sonucu deponun Actions sekmesinden izleyebilirsiniz. İsterseniz deploy adımından önce testlerinizi çalıştıran bir adım ekleyerek yalnızca testleri geçen kodun yayınlanmasını sağlayabilirsiniz.

Güvenlik önerileri

  • Gizli bilgileri depoya koymayın. .env dosyasını .gitignore'a ekleyin, sunucuda elle oluşturun ve depoda yalnızca değerleri boş bir .env.example tutun.
  • Deploy kullanıcısının yetkilerini sınırlayın. Kullanıcının sudo ile yalnızca uygulama servisini yeniden başlatabilmesi gerekiyorsa sudo visudo ile tek bir komuta izin verin:
    deploy ALL=(root) NOPASSWD: /bin/systemctl restart proje
    
  • Actions anahtarını yalnızca deploy için kullanın. Bu anahtar sızarsa authorized_keys dosyasından silmeniz yeterli olur.
  • SSH'ı koruyun. Şifreli girişi kapatın ve otomatik saldırılara karşı Fail2ban kurun.

Geri alma

Hatalı bir sürüm yayınladıysanız sunucuda önceki commit'e dönün:

cd /var/www/proje
git log --oneline -5
git reset --hard <onceki-commit>
npm ci && npm run build && pm2 reload proje

Daha temiz bir yol, hatalı commit'i kendi bilgisayarınızda git revert ile geri alıp ana dala göndermektir; otomatik deploy süreci düzeltilmiş sürümü kendisi yayınlar ve depo geçmişi sunucuyla tutarlı kalır. Veritabanı değişikliği (migration) içeren yayınlardan önce veritabanının yedeğini almayı alışkanlık hâline getirin; kodu geri almak veritabanını geri almaz.

Git ile deploy için Nodesty sunucuları

Nodesty AMD Ryzen 9 9950X VDS paketleri yüksek tek çekirdek hızıyla derleme adımlarını hızlandırır ve uygulamanıza düşük cevap süresi sağlar; AMD EPYC 7763 VDS paketleri ise aynı sunucuda birden fazla uygulama ve veritabanı çalıştırmak için bol RAM sunar. Tam root erişimiyle Git, Node.js, PHP ve Docker'ı dilediğiniz gibi kurabilir, NVMe disk ve 7 gün saklanan ücretsiz günlük yedeklemeyle projelerinizi güvende tutabilirsiniz.

Sıkça Sorulan Sorular

Dosyaları FTP ile yüklemek yerine neden Git kullanmalıyım?

Git ile her yayın bir commit'e karşılık gelir; sunucuda hangi sürümün çalıştığını her zaman bilirsiniz ve bir sorun çıktığında tek komutla önceki sürüme dönersiniz. Elle dosya yüklemek ise eksik ya da eski dosyaların sunucuda kalmasına ve kimin neyi değiştirdiğinin bilinmemesine yol açar.

Deploy anahtarı ile kişisel SSH anahtarı arasındaki fark nedir?

Deploy anahtarı yalnızca tek bir depoya erişebilen ve genellikle yalnızca okuma yetkisi olan bir anahtardır. Sunucu ele geçirilse bile saldırgan yalnızca o depoyu okuyabilir; kişisel anahtarınızın erişebildiği bütün depolara ve hesabınıza ulaşamaz.

.env dosyasını Git'e eklemeli miyim?

Hayır. Şifreler, API anahtarları ve veritabanı bilgileri Git geçmişine bir kez girdiğinde oradan tamamen silmek zordur. .env dosyasını .gitignore'a ekleyin, sunucuda elle oluşturun ve depoda yalnızca değerleri boş bir .env.example dosyası tutun.

Deploy sırasında site kesintiye uğrar mı?

Basit bir git pull ve yeniden başlatma, birkaç saniyelik bir kesintiye yol açabilir. pm2 reload gibi araçlar uygulamayı sırayla yeniden başlatarak kesintiyi önler. Kesintinin hiç istenmediği projelerde her yayını ayrı bir klasöre kurup hazır olduğunda bir sembolik bağlantıyla yeni sürüme geçmek yaygın bir yöntemdir.

GitHub yerine GitLab ya da kendi Git sunucumu kullanabilir miyim?

Evet. Deploy anahtarı ve git pull mantığı her Git sağlayıcısında aynıdır; GitLab'de de depo ayarlarında deploy anahtarları bulunur. Otomatik deploy için GitHub Actions yerine GitLab CI/CD ya da kendi Git sunucunuzda bir post-receive kancası kullanabilirsiniz.

Yanlış bir sürümü yayınladım, nasıl geri dönerim?

Sunucudaki proje klasöründe git log ile önceki commit'i bulun, git reset --hard ile o commit'e dönün ve uygulamayı yeniden derleyip başlatın. Daha temiz bir yol, hatalı commit'i git revert ile geri alıp ana dala göndermek ve normal deploy sürecinin çalışmasına izin vermektir.

Nodesty

Yazar hakkında

Nodesty Ekibi · Altyapı ve Destek

Nodesty ekibi sunucularımızı, ağımızı ve DDoS korumamızı her gün işletir ve müşteri destek taleplerini 7/24 yanıtlar. Bu rehberler o deneyimden yazılır.

İlgili yazılar

Sunucunuzu şimdi başlatın.

Nodesty'nin üstün altyapısı ile projelerinizi özgürce inşa edin ve sınır tanımadan ölçeklendirin.

                                                                                                                                                                                                                            
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            
                                                                                                                             ············································                                                   
                                                ··································································································..........···························                                     
                                       ················..........................................................................................................................··············                             
                                  ·············.................::::::::::::::::::::::::::::::::::::::::::::::....................:::::::::::::::::::::::::::::::::::::::................···········                        
                             ············................:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::............·········                     
                         ············.................:::::::::::::::::::::::::::::::::::::::::::::::::::------------::::::::::::::::::::::::::::::----------------:::::::::::::::::::::..........········                  
                    ············......................::::::::::::::::::::::::::::::::::::------------------------------------------------------------------------------------:::::::::::::.........········                
                ··········.............................................::::::::::::::::::-------------==========================================-----------------------------------:::::::::::........·······               
             ········..................:.....................................::::::::::--------=======+++++++++++++++++++++++++++++++++++++=========================------------------::::::::::.......·······              
           ······.........::::::::::::::::::::................................:::::::-----=====++++xxxxxx**************************xxxxxxxxx++++++++++++++===================------------::::::::.......·······             
          ·····.......:::::::::::::::::::::::::::.............................:::::----===+++xxx****%%%%&&&&&&#############&&&&&&&%%%%%*******xxxxxxxx++++++++++++++==============----------:::::::......······             
         ····......::::::::-------------:::::::::::..........................::::---===+++xx***%%%&&&####@@@@@@@@@@@@@@@@@@@@@@@@####&&&&&%%%%*******xxxxxxxxx+++++++++++++===========--------::::::......·····             
        ····.....:::::::--------------------:::::::::.......................::::---===++xxx**%%&&&###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###&&&&%%%%%********xxxxxxxxxxx++++++++++++========------::::::.....······            
        ····.....:::::--------------------------::::::::....................::::---===++xx***%%&&&####@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###&&&&&%%%%%**********xxxxxxxxxxxxx+++++++++=======------:::::.....·····            
        ····....::::::-------=============---------:::::::::................:::::---===+++xx***%%%&&&#####@@@@@@@@@@@@@@@@@@@@@@@@@#####&&&&&%%%%%%*************xxxxxxxxxxxxxx+++++++++======-----:::::....·····            
         ····....:::::-------================---------:::::::::...............:::::----===++++xxx***%%%%&&&&&&#################&&&&&&%%%%%%%*******************xxxxxxxxxxxxxxxxx++++++++======----:::::....·····            
         ·····....:::::--------=================---------::::::::::..............:::::::-----====+++++xxxxxx**************************xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx++++++++=====-----::::....·····            
          ·····.....:::::--------=================----------:::::::::::.................:::::::::-------=============++++++++++++++++++++++++++++++++++++xxxxxxxxxxxxxxxxxxxxxxx++++++++======-----::::....·····            
            ·····.....:::::::----------===========-------------::::::::::::.........................::::::::::::::::::------------------=============+++++++++++++++++++++++++++++++++=======-----::::.....·····            
              ······......:::::::---------------------------------:::::::::::::........................................:::::::::::::::-----------============+++++++++++++++++++++========------:::::.....·····             
                 ······........:::::::::---------------------------:::::::::::::::::...........................................:::::::::::::------------=============================--------::::::.....······              
                    ·········.........:::::::::::::::-------------::::::::::::::::::::::::.......................................::::::::::::::::--------------------------------------::::::::......·······                
                          ··········............::::::::::::::::::::::::::::::::::::::::::::::::::................................::::::::::::::::::::::::::-------------:::::::::::::::.........········                   
                                  ············..................:::::::::::::::::::::::::::::::::::::::::::.........................:::::::::::::::::::::::::::::::::::::................···········                        
                                             ················.............................................................................................................·················                                 
                                                           ······················................................................................···························                                                
                                                                               ·········································································