Jenkins ile Docker İmajı Derlemek
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 -dJenkins 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=falseSonra repomuz için hazırlayın:
- http://localhost:3000 adresini açın
studentkullanıcı adı vestudentparolasıyla giriş yapın
- My Repositories bölümündeki
+işaretine tıklayıp yeni bir repo oluşturun
- repo adını
devsecopsyapı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
studentkullanıcı adı vestudentparolası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;
-jreimajı-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'ındakiwhoamiderlemesiscratchile 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/rngklasö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 $PATHhatası 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-hubyapın
Sonra Jenkinsfile'ı düzenleyin:
REPOSITORY="courselabs"ortam değişkeninin değerini kendi Docker HubID'nizle değiştirin
- _örneğin benim Hub ID'm
sixeyed, dolayısıyla benim ayarımREPOSITORY="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-hubkimlik bilgilerinizin doğru olduğunu kontrol edin REPOSITORYortam değişkeninizin kimlik bilgilerindeki Docker Hub ID ileeş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'icourselabs/rng-api:21.12— 21.12 sürümünün en son build'icourselabs/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
-visimsiz 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 existshatası verir.
Bu komut yalnızca bu lab'in baslattigi container'lari kaldırır. Tamamen temiz bir başlangıç istiyorsanız
docker psile hâlâ çalışan varsa görebilirsiniz.
Ve Gitea remote'unu kaldırın:
git remote rm gitea