Github Webhooks ile Otomatik Deploy Yapmak

  

        

Ön Hazırlık

       Geliştirdiğimiz projeleri hızlı bir şekilde deploy yapmak, yazdığımız testleri kontrol etmek ve kod kalitesini sağlamak adına yaygın kullanılan CI/CD aralarından biri olan Jenkins'in kurulumuna geçmeden önce CI/CD nedir diye merak ediyorsanız bu makaleyi okuyabilirsiniz.

       Kurulum yapacağınız Ubuntu sunucu yoksa veya test için yeni bir sunucu oluşturacaksanız bu makaledeki adımları takip edebilirsiniz.

       Jenkins'i henüz kurmadıysanız da bu makaledeki adımları uygulayarak kurabilirsiniz.

       Jenkins'e Github'ta yer alan projenizi eklemek için bu makaledeki adımları uygulayabilirsiniz.

 

       Önceki yazımızda oluşturduğumuz Jenkins tanımında kodumuzu farklı bir dizine build yapıyorduk. Şimdi ise projemizi doğrudan sunucu üzerinde çalışıp, kullanıcı isteklerine cevap verebilecek şekilde derleyeceğiz. Sunucu üzerinde ayrıca Nginx kurup istekleri yölendirecek şekilde tanımlayacağız. Ardından Github Webhooks ile entegre olup otomatil deploy yapılmasını sağlayacağız.

 

Projenin Publish Modda Derlenmesi

       Jenkins üzerinde "Freestyle project" tipinde yeni bir tanım oluşturalım.

       Önceki yazımızda olduğu gibi projeyi ekleyip key'imize bağlayalım. Eğer direkt bu makaleye geldiyseniz bir önceki yazımızı okumanızı tavsiye ederim bu adımla ilgili.

       Bu tanımda da "Delete workspace before build starts" kutusunu da işaretleyelim.

       Build kısmına aşağıdaki script'i kendi projenize göre düzenleyip ekleyin.

dotnet publish JenkinsDemoApi.sln -c Release  -o /home/ubuntu/jenkins-demo-api

 

 

       Bu şekilde tanımımızı yapıp bir çalıştıralım. Gördüğümüz gibi proje dosyalarımız başarılı bir şekilde oluştu.

       Jenkins tanımını şimdilik bu şekilde bırakalım, sunucu üzerine web server kurulumu yapıp gerekli ayarlamaları yaptıktan sonra bu tanım üzerinde tekrardan eklemeler yapacağız.

 

Ubuntu Nginx Kurulumu

       Sunucumuzda yayınlayacağımız projemize gelen istekleri doğru bir şekilde karşılayıp hem sunucu içerisinde doğru uygulamaya yönlendirmek, hem de istekte bulunan istemciye(client) doğru cevabı dönebilmek ve bu trafiğin doğru bir şekilde yönetimini, güvenliğini sağlamak için web server çözümleri kullanılır. Windows'ta aşinalığınız varsa bunun IIS'e karşılık da geldiğini düşünebilirsiniz fakat doğrudan karşılık geldiğini söylemeyiz. 

       Linux dağıtımlarında web server için genellikle nginx, apache ve lighttpd yaygın olarak kullanılır. Performans, yönetim ve özellikleri bakımından ben nginx'i tercih etmekteyim. Bunun için aşağıdaki komutu sunucumuza bağlanıp çalıştıralım kurulum sırasında onay isteyecektir onu da onaylayalım.

sudo apt-get install nginx

       Kurulum tamamlandıktan sonra sunucumuzun IP adresine doğrudan browser üzerinden bir istek attığımızda bizi nginx'in karşıladığını göreceğiz.

       Nginx, varsayılan olarak 80 portundan gelen HTTP isteğini kendi karşılama ekranına yönlendirir. Eğer biz de belirli bir domain adından gelen isteği sunucu üzerindeki bir uygulamaya baktırmak istersek aşağıdaki gibi tanımlama yapmamız gerekmektedir.

       Ben bu makale dahilinde version.caylakyazilimci.com subdomaini oluşturup yeni oluşturduğumuz sunucuya yönlendirdim. Siz de varsa eğer kendi domain'iniz altında bir subdomain oluşturup yönlendirebilirsiniz eğer bir domaininiz yoksa ip adresinden istek yapabilirsiniz.

 

       Sunucu üzerinde aşağıdaki komutu çalıştırıp host dosyamıza gidelim. 

sudo nano /etc/nginx/sites-available/default

       Bu dosya altında sunucu üzerinde çalışan sitelerinizi tanımlayabilir, gerekli port yönlendirmelerini, güvenlik ayarlamalarını yapabilirsiniz. 

       Dosya içindekileri temizleyip aşağıdaki tanımı ekleyelim.

server {
         listen 80;
         server_name   _;
         location / {
         proxy_pass http://localhost:5000;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection keep-alive;
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Forwarded-Proto $scheme;
         }
}

       Ben ek olarak oluşturduğum subdomain için de aşağıdaki gibi eklemeyi yaptım. Bu sayede ilgili subdomain'den gelen istek sunucu üzerindeni localhost:5000 portunda çalışan uygulamaya yönlendirilecek. "server_name" alanında birden fazla domaini "," ile ekleyebiliyorsunuz.

       Gelen istekleri uygulamamızın çalışacağı porta yönlendirdik fakat uygulamamızın sunucu üzerinde çalışması için service olarak eklememiz gerekiyor. Bunun için aşağıdaki kodu çalıştıralım;

sudo nano /etc/systemd/system/jenkins-demo-api.service

       Açılan ekrana aşağıda yer alan değerleri yapıştıralım. Yapıştırırken şu alanlara dikkat edin;

       WorkingDirectory; jenkins üzerinden proje dosyalarını attığınız klasör,

       ExecStart; burada son kısımda yer alan dosya yolu da yine sizin dosyaları attığınız klasör altında "uygulama-adınız.dll" formatında olmalı

        [Unit]
        Description=Jenkins Demo API

        [Service]
        WorkingDirectory=/home/ubuntu/jenkins-demo-api
        ExecStart=/usr/bin/dotnet /home/ubuntu/jenkins-demo-api/JenkinsDemoApi.dll
        Restart=always
        RestartSec=10
        SyslogIdentifier=jenkins-demo-api
        Environment=ASPNETCORE_ENVIRONMENT=Production

        [Install]
        WantedBy=multi-user.target

       Bu tanımlamarı girip kaydettikten sonra aşağıdaki komutla servisimizi aktifleştirelim.

       Burada son kısımda yer alan "jenkins-demo-api", önceki adımda tanımladığınız "system/jenkins-demo-api.service" isim ile aynı olmalı.

 sudo systemctl enable jenkins-demo-api

       Servisi başlatmak için aşağıdaki kodu çalıştıralım;

sudo systemctl start jenkins-demo-api

       Bu işlemlerden sonra servisimizin durumunu kontrol etmek için de aşağıdaki gibi durumunu sorgulayabilirsiniz;

sudo systemctl status jenkins-demo-api

       Sunucu üzerindeki yönlendirmelerimizi de yaptıktan sonra browser üzerinden API üzerinde oluşturduğumuz endpointe bir istek attığımızda aşağıdaki gibi versiyon bilgisini göreceğiz.

       Jenkins üzerinden elle oluşturduğumuz dosyalar ile servisimizi ayağa kaldırdığımıza göre şimdi sıra bu süreci otomatize etmeye geldi :) 

 

Jenkins ile Deploy Yapmak

       İlk olarak deploy sırasında servisi durdurup başlatmak gerektiği için Jenkins kullanıcısın sudo komutlarını çalıştırabilmesi için ufak bir ekleme yapmamız gerekiyor. Bunun için aşağıdaki önce komutu çalıştıralım;

sudo visudo

       Ardında açılan dosyada alta aşağıdaki satırı ekleyelim;

jenkins ALL=(ALL) NOPASSWD: ALL

       Eklemeyi yaptıktan sonra dosyayı kaydedip çıkabilriz.

 

       Jenkins üzerinden oluşturduğumuz publish tanımına gelip görseldeki gibi service'i durdurup başlattığımız adımları ekleyelim. Eklediğimiz "Execute shell" tanımlarını sürükle-bırak ile sıralayabiliyoruz. Aşağıdaki görseldeki sırayla olduğunda emin olun.

sudo systemctl stop jenkins-demo-api

sudo systemctl start jenkins-demo-api

       Burada dosyaları güncellemeden önce servisi durduruyoruz, publish alıp dosyaları güncelliyoruz ve servisimizi güncel kodlarla yayına alıyoruz.

 

       Aşağıdaki adımları ekleyip API'ımız üzerindeki versiyon bilgisini "ApiVersion" : "1.1.1" olarak güncelleyip Github'a pushlayalım, ardından Jenkins üzerindeki tanımımıza gelip "Build Now" ile manuel tetikleyelim. Loglara baktığımda aşağıdaki gibi tamamlandığını göreceksiniz.

Browser üzerinden kontrol ettiğimizde de versiyon bilgisinin güncellendiğini göreceksiniz. Yani master'a pushladığımız son geliştirmeleri tek bir tuşa basarak yayına almış olduk.

 

 

Bizim için yeterli mi?

Tabi ki hayır :) 

 

Github Hook ile Jenkins Tetiklemek

       Master'a gönderdiğimiz kodları elle tetikleyip canlı ortama çıktık. Ama istersek bunu master'a her commit veya merge yapıldığında otomatik tetikletebiliriz. Bunun için "Github WebHook" servisini kullanacağız.

       Bunun için öncelikle Jenkins'e "Github Integration" eklentisini kuruyoruz. Bunun için ana sayfadayken sırasıyla Manage Jenkins > Manage Plugins > Available tab'ı altında "Github Integration" 'ı bulup işaretliyoruz ve "Download now and install after restart"'a tıklıyoruz.

       İşlem tamamlandığında altta yer alan "Restart Jenkins ..." kutusuna tıklıyoruz. Bu işlem sonrasında Jenkins servisimiz yeniden başlayacaktır.

       İşlem tamamlandıktan sonra tekrardan giriş ekranına yönlendirecek sizi. Tekrar giriş yapıp publish tanımımıza gelelim. Burada "Build Trigger" altında bulunan aşağıdaki kutuyu işaretleyelim ve kaydedelim.

 

       Bu sayede jenkins üzerinde bu job için Github'dan tetiklenecek şekilde dinlemesini sağladık. Son aşama olarak da Github'a gidip projemizin "Settings" sekmesi altında "Webhooks"'a tıklayalım. Burada açılan sayfada sağ üstte yer alan "Add webhook" butonuna tıklayalım.

Açılan sayfada;

Content type; application/json olarak değiştirelim

diğer alanların da aşağıdaki gibi olduğunu kontrol edip kaydedelim.

Bu ekranda "Let me select individual events" altında projeniz ile ilgili yapılan farklı bir işlemde istek atılmasını da belirleyebiliyorsunuz. Biz master'a yapılan yeni değişikliklerde tetiklenmesini istediğimiz için "Just the push event" ile devam ettik ama isterseniz diğer ayarları da inceleyebilirsiniz.

 

       Şimdi API projemizde versiyon değerini tekrar bir arttırıp pushlayalım. Jenkins'te kısa süre içerisinde otomatik tetiklendiğini göreceksiniz. Bu sayede master branch'inize gelen her kodda otomatik deployunuzu yapıyor olacaksınız.

Browser üzerinden kontrol ettiğimde versiyonun güncellenip kendiliğinden deploy olduğunu görüyoruz.

Şimdi de ayrı bir branch oluşturup versiyon arttırımını o branch üzerinde yapacağım. Ardından pull request oluşturup master'a merge'leyeceğim. 

Master'a merge yaptıktan sonra Jenkins'in otomatik tetiklendiğini göreceksiniz. Link üzerinden endpointe baktığımda versiyonun yine güncellendiğini göreceğiz.

 

  

 

 

 

Kapanış

       Sıfırdan sunucu kurulumu ve proje oluşturmayla başladığımız bu seride otomatik deployumuzu yaparak noktaladık. Bir projenin en başından son aşamasına kadar ele aldığımız bu seriyle ilgili düşüncelerinizi ve yorumlarınızı paylaşabilirsiniz. 

       Evden Buluta - DevOps Serisi içerisinde yer alan diğer yazılara ulaşmak için tıklayın.

 

 

 

 

Add comment