labs

Bu lab modernize edildi ama ucтan uca dogrulanmadi. Takilirsaniz bize bildirin.

Jenkins ile Docker İmajı Derlemek

60 dkdockerGitHub'da gor
Bu sayfada

Jenkins ile Docker İmajı Derlemek

Docker motoruna erişimi olan container'lar çalıştırabilirsiniz — böylece container içindeki uygulama, başka container'lar çalıştırmak veya imaj derlemek için Docker komut satırını kullanabilir. Bu, temiz bir CI/CD kurulumu sağlıyor: Jenkins'i bir container içinde çalıştırıp, uygulamalarınızı çok aşamalı Dockerfile'larla derleyen pipeline'lar kullanıyorsunuz. Pipeline'lar ayrıca işlevselliği hızlıca sınamak için yeni imajlardan container çalıştırabiliyor.

Bu yaklaşımla tüm build altyapınız taşınabilir hale geliyor. Jenkins sunucusunu herhangi bir Docker motorunda çalıştırıp, pipeline'larınızı yükleyip, başka hiçbir araç kurmadan her tür yazılımı derleyebilirsiniz. Kimlik bilgilerini de Jenkins'te saklayabilirsiniz; böylece diğer servislerle kimlik doğrulaması yapıp pipeline'dan Docker Hub'a imaj gönderebilir ya da üretim ortamınıza dağıtım yapabilirsiniz.

Kaynaklar

Basit Bir Java İmajı Derlemek

Bu Dockerfile'ı, bu Jenkinsfile ile derleyerek başlayacağız. Önceden derlenmiş bir Java uygulamasını bir Docker imajına paketleyip imajdan bir container çalıştıracak. Build veya test aşamaları başarısız olursa pipeline da başarısız olur.

Önce şu Docker Compose belirtimiyle Jenkins ve Gitea'yı çalıştırın:

docker compose -f labs/pipeline/infra/docker-compose.yml up -d

Jenkins servisi Docker socket'ini bağlayacak şekilde yapılandırılmış; container, üzerinde çalıştığı Docker motoruyla bu sayede konuşabiliyor.

Bu, boş veritabanlı yeni bir Gitea sunucusu; önce kullanıcınızı oluşturun:

docker compose -f labs/pipeline/infra/docker-compose.yml exec -u git gitea gitea admin user create --admin --username student --password student --email [email protected] --must-change-password=false

Sonra repomuz için hazırlayın:

  • http://localhost:3000 adresini açın
  • student kullanıcı adı ve student parolasıyla giriş yapın
  • My Repositories bölümündeki + işaretine tıklayıp yeni bir repo oluşturun
  • repo adını devsecops yapın ve Create Repository tıklayın

Gitea sunucunuzu remote olarak ekleyip repoyu gönderin:

# Jenkins labindan kalmis olabilir - gordugunuz hatalari yok sayin:
git remote add gitea http://localhost:3000/student/devsecops.git

git push gitea main

Şimdi Jenkins'te şu bilgilerle bir pipeline oluşturabiliriz:

  • job adı = docker
  • Git URL = http://gitea:3000/student/devsecops.git
  • branch specifier = refs/heads/main
  • Jenkinsfile yolu = labs/pipeline/docker/Jenkinsfile

📋 Jenkins arayüzünü açıp yeni pipeline job'ını oluşturun.

Nasıl yapılacağını bilmiyor musunuz?
  • http://localhost:8080 adresini açın
  • student kullanıcı adı ve student parolasıyla giriş yapın
  • sol menüden New item tıklayın
  • proje tipini Pipeline seçin
  • pipeline penceresinde açılır listeden Pipeline script from SCM seçin
  • pipeline bilgilerini girin

Kaydedip build'i çalıştırın.

📋 Build çıktısını inceleyin. Derlediği Docker imajının adı ne? Test container'ının çıktısı ne?

Takıldınız mı?

Build aşamasının loglarını açın; imaj etiketinin docker.io/courselabs/hello-world:1 olduğunu göreceksiniz.

Test aşaması loglarında container çıktısının Hello, World metni olduğunu göreceksiniz.

Bu basit bir örnek, ama amacımız yalnızca ikili dosyaları imajlara paketlemek değil — onları kaynak koddan derlemek istiyoruz; bunu da çok aşamalı build ile yapabiliriz.

Jenkins'te Çok Aşamalı Build

Çok aşamalı build'in özel bir tarafı yok — dizüstünde çalıştırabildiğimiz her Docker build'i Jenkins container'ında da aynı şekilde çalışır:

  • multi-stage/Dockerfile — aynı Java uygulamasını

    kaynaktan derliyor, dolayısıyla ayrı bir derleme adımına ihtiyacımız kalmıyor

  • multi-stage/Jenkinsfile — etiketi üretmek için

    ortam değişkenleri kullanarak imajı derliyor, sonra bir test container'ı çalıştırıyor

Bu dosyalar zaten Gitea sunucunuzda; dolayısıyla Jenkins'te labs/pipeline/multi-stage/Jenkinsfile script'ini çalıştıracak yeni bir pipeline oluşturabilirsiniz.

📋 multi-stage adında yeni bir pipeline oluşturup çalıştırın.

Nasıl yapılacağını bilmiyor musunuz?

http://localhost:8080/view/all/newJob adresinde Jenkins arayüzünden yeni bir öğe oluşturun, adını multi-stage yapın, tipini Pipeline seçin ve mevcut bir pipeline'ı kopyalamak için Copy from kutusuna docker yazın.

Script yolunu labs/pipeline/multi-stage/Jenkinsfile olarak değiştirin.

Save, sonra Build Now tıklayın.

Build, alışık olduğumuz aşamalarla çalışıyor. Jenkins'in Docker motorunuzu paylaştığını hatırlayın; derlediği imajlar docker komutlarıyla sizin de kullanımınıza açık.

📋 Build'den çıkan yeni imajın boyutu ne? SDK ile karşılaştırıldığında nasıl?

Takıldınız mı?

Ayrıntıları görmek için makinenizdeki imajları listeleyebilirsiniz:

# pipeline'dan derlenen imaj:
docker image ls courselabs/multi-stage:1

# Docker Hub'daki java sdk imaji:
docker pull eclipse-temurin:25-jdk
docker image ls eclipse-temurin:25-jdk 

Uygulama imajınız SDK imajından küçük - Java çalışma zamanını taşıyor ama derleyiciyi ve derleme araçlarını taşımıyor. Bu Temurin imajlarında kazanç 100MB civarında; -jre imajı -jdk'nın kabaca beşte dördü. Son aşamayı daha ince bir imaja (örneğin Alpine tabanlı bir JRE) dayandırırsanız aradaki fark çok açılır - multi-stage lab'ındaki whoami derlemesi scratch ile tam olarak bunu yapıyor.

Docker Compose ile Derlemek

Bu Jenkins container imajında docker compose komutu da kurulu; dolayısıyla tek komutla birden fazla imaj derleyebiliriz.

Rastgele sayı uygulamasını kaynaktan derleyeceğiz:

  • compose/Jenkinsfile — uygulamayı

    labs/compose-build/rng klasöründe derliyor; Push aşaması yorum satırına alındığı için yalnızca Build aşaması çalışacak

  • API Dockerfile'ı — .NET SDK ve

    çalışma ortamı imajlarını kullanan çok aşamalı bir build

Yani bu bir .NET uygulaması. Hile yapmadığımızdan emin olmak için, .NET'in kurulu olmadığını doğrulamak üzere şu komutu Jenkins container'ı içinde çalıştırın:

# bu basarisiz olacak
docker compose -f labs/pipeline/infra/docker-compose.yml exec jenkins dotnet --version

not found in $PATH hatası göreceksiniz, çünkü container'da .NET yok. Sorun değil; çünkü bu çok aşamalı bir build ve derleme container'ların içinde çalışacak.

📋 labs/pipeline/compose/Jenkinsfile script yolundan compose adında yeni bir pipeline oluşturup çalıştırın.

Nasıl yapılacağını bilmiyor musunuz?

http://localhost:8080/view/all/newJob adresinde Jenkins arayüzünden yeni bir öğe oluşturun, adını compose yapın, tipini Pipeline seçin ve mevcut bir pipeline'ı kopyalamak için Copy from kutusuna docker yazın.

Script yolunu labs/pipeline/compose/Jenkinsfile olarak değiştirin.

Save, sonra Build Now tıklayın.

Çıktıyı kontrol edin — build başarıyla çalışıp imajlar üretmeli.

📋 Kaç imaj derlendi? İmaj etiketindeki 21.12 kısmı nereden geliyor?

Takıldınız mı?

Build aşaması logları iki imajın derlendiğini gösterecek: courselabs/rng-api:21.12-1 ve courselabs/rng-web:21.12-1.

21.12 sürüm döngüsü; Jenkinsfile'da bir ortam değişkeniyle ayarlanıyor.

İmaj etiketindeki registry ve repository adları için ortam değişkenleri kullanılıyor; böylece imajların nereye gönderileceği kolayca değiştirilebiliyor.

Docker Hub'a Göndermek

Pipeline'ımızın yayınlama kısmı imajları Docker Hub'a gönderecek. Bunun için üç şeye ihtiyacınız var:

  • bir Docker Hub hesabı — yoksa oluşturun, ücretsiz

    katman yeterli

  • Docker Hub kimlik bilgilerinizin Jenkins'te saklanması
  • Jenkinsfile'da bir değişiklik: imaj etiketlerinin sizin Docker Hub kullanıcı

    adınızı taşıması

Docker Hub hesabınız olduğunda ayarlarınıza gidip bir erişim belirteci (access token) üretebilirsiniz. Belirteci kopyalayın — gerçek parolanızı Jenkins'te saklamamak için giriş yaparken onu kullanacaksınız.

Şimdi Jenkins'te bir kimlik bilgisi oluşturun:

  • Manage Jenkins > Credentials > System > Global credentials yolunu

    açın (http://localhost:8080/manage/credentials/store/system/domain/_/)

  • Add Credentials tıklayın ve Kind alanının Username with password

    olduğundan emin olun

  • Username alanına Docker Hub kullanıcı adınızı girin (e-posta adresinizi

    değil)

  • Password alanına erişim belirtecinizi girin
  • ID alanında kimlik bilgisinin adını docker-hub yapın

Sonra Jenkinsfile'ı düzenleyin:

  • REPOSITORY="courselabs" ortam değişkeninin değerini kendi Docker Hub

    ID'nizle değiştirin

  • _örneğin benim Hub ID'm sixeyed, dolayısıyla benim ayarım

    REPOSITORY="sixeyed" olacak_

  • Push aşamasını yorumdan çıkarın — baştaki /* ve sondaki */

    işaretlerini silin

Değişikliklerinizi gönderin:

git add labs/pipeline/compose/Jenkinsfile  

git commit -m 'Added push'

git push gitea main

📋 compose job'ını yeniden çalıştırın ve imajların derlenip kendi kullanıcı adınız altında Docker Hub'a gönderildiğini doğrulayın.

Nasıl yapılacağını bilmiyor musunuz?

Tüm build aşamalarını kontrol edin. Push aşaması başarısız olursa loglara bakın. Sorun, Docker Hub'a kimlik doğrulamasıyla ilgili olacak:

  • Jenkins'teki docker-hub kimlik bilgilerinizin doğru olduğunu kontrol edin
  • REPOSITORY ortam değişkeninizin kimlik bilgilerindeki Docker Hub ID ile

    eşleştiğini kontrol edin

  • imajların, Docker Hub ID'nizi içeren beklenen imaj adıyla derlendiğini

    doğrulayın

Hata mesajı alırsanız sorunun ne olduğu anlaşılır olmalı. Build'i çalıştırmayı başardığınızda imajların Docker Hub'a gönderildiğini göreceksiniz; benim örneğim gibi: https://hub.docker.com/r/sixeyed/rng-api/tags

Makinenizde Jenkins, Gitea veya .NET kurulu değil, muhtemelen. Ama artık bir .NET uygulaması için Docker imajlarını tamamen otomatik bir pipeline ile derleyip gönderebiliyorsunuz; pipeline ihtiyaç duyduğu tüm bağımlılıkları kendisi getiriyor.

Lab

Docker imaj etiketleri tipik olarak sürümleme için kullanılır. Bizim imajlarımız, imaj sürümü olarak bir sürüm döngüsü ve bir build numarası taşıyor. İmajın daha az belirgin sürümlerini de sunmak istiyoruz, örneğin:

  • courselabs/rng-api:21.12-3 — 21.12 sürümünün 3 numaralı build'i
  • courselabs/rng-api:21.12 — 21.12 sürümünün en son build'i
  • courselabs/rng-api:latest — en son sürümün en son build'i

latest varsayılan etiket olduğu için kullanıcılar en güncel sürümü almak için courselabs/rng-api, sürümün en son build'ini almak için courselabs/rng-api:21.12, belirli bir build'i çalıştırmak için ise courselabs/rng-api:21.12-3 kullanabilir.

İmajları ek etiketlerle derlemek için kullanabileceğimiz birkaç Compose override dosyası var:

Jenkinsfile'ı, bu etiketleri ekleyip build'in parçası olarak Docker Hub'a gönderecek şekilde genişletin. Hedef, her build'in belirli imaj etiketini göndermesi ve diğer etiketleri güncellemesi; böylece aynı imaj digest'i için takma ad gibi çalışacaklar:

Jenkinsfile değişikliklerinizi Gitea'ya gönderip Jenkins'te yeni bir build çalıştırmanız gerekecek. Her şey çalıştığında makinenizdeki Docker ile latest imajını çekin. Metadata içinden build bilgisini ve Git hash'ini bulabiliyor musunuz?

Takıldınız mı? İpuçlarına bakın veya çözümü inceleyin.


Temizlik

Bu lab'ın container'larını kaldırın:

docker compose -f labs/pipeline/infra/docker-compose.yml down -v

-v isimsiz volume'ları da siler. Olmadan Gitea'nın veritabanı hayatta kalır ve lab'ın sonraki çalıştırmasında kullanıcı oluşturma adımı user already exists hatası verir.

Bu komut yalnızca bu lab'in baslattigi container'lari kaldırır. Tamamen temiz bir başlangıç istiyorsanız docker ps ile hâlâ çalışan varsa görebilirsiniz.

Ve Gitea remote'unu kaldırın:

git remote rm gitea