Merhaba! Önceki dersimizde, CI işlem hattımızı kullanarak PySpark ETL uygulamamızdan bir Docker imajı oluşturup bunu Docker Hub'a otomatik olarak göndermeyi başardık. Bu önemli bir adımdı, ancak imajımızı latest olarak etiketledik. Bu, geliştirme sırasında pratik olsa da, sürüm kontrolü ve güvenilir dağıtımlar için önemli bir eksiklik yaratır.
Bugün bu eksikliği gidereceğiz.
Bugünkü Öğrenme Hedefimiz: Docker imajlarını, onları oluşturan Git commit SHA'sı ile etiketleyerek tam sürüm izlenebilirliği sağlamak.
Neden latest Etiketinden Kaçınmalıyız?
latest etiketi, bir Docker imajı için "hareketli bir hedeftir". Her yeni imaj gönderildiğinde, latest etiketi en sonuncusunu işaret edecek şekilde güncellenir. Bu durum şu sorunlara yol açar:
- Belirsizlik: Bir sunucuda çalışan
:latestetiketli bir imaj gördüğünüzde, "Bu imaj tam olarak hangi kod versiyonunu içeriyor?" sorusunun net bir cevabı yoktur. - Güvenilmez Geri Almalar (Rollbacks): Bir dağıtımda sorun çıkarsa ve önceki sürüme dönmek isterseniz, bir önceki "latest" imajına geri dönmenin kolay bir yolu yoktur.
- Hatalı Dağıtımlar: Kubernetes gibi orkestrasyon sistemleri, imajın
imagePullPolicyayarına bağlı olarak, aynı:latestetiketine sahip olsa bile her zaman en son imajı çekmeyebilir. Bu, farklı sunucularda kodun farklı sürümlerinin çalışmasına neden olabilir.
Çözüm: Git Commit SHA ile Sürümleme
Her git commit işlemi, o anki kod tabanınızın durumunu temsil eden benzersiz ve değişmez bir kimlik (SHA - Secure Hash Algorithm) oluşturur.

Bu benzersiz kimliği Docker imajlarımız için bir etiket olarak kullanarak, kod ile onu çalıştıran imaj arasında doğrudan ve değişmez bir bağ kurarız. Bir imajın sha-9fd7d12 olarak etiketlendiğini gördüğünüzde, o imajın içinde tam olarak 9fd7d12 commit'indeki kodun olduğunu bilirsiniz. Bu, CI/CD süreçlerinde izlenebilirlik (traceability) ve tekrarlanabilirlik (reproducibility) için temel bir prensiptir.
Nihai hedefimiz, container registry'mizin aşağıdaki gibi görünmesidir: Her commit, kendi benzersiz etiketine sahip bir imaj üretir.

docker/metadata-action ile Tanışma
Bu sürümleme stratejisini GitHub Actions'da uygulamanın en standart ve güçlü yolu, Docker tarafından geliştirilen docker/metadata-action eylemini kullanmaktır. Bu eylemin tek bir görevi vardır: Git ve GitHub olaylarından (event) gelen bilgilere (commit SHA, branch adı, tag adı vb.) dayanarak Docker imajları için akıllı etiketler (tags) ve etiketler (labels) üretmek.
docker/metadata-action - GitHub
docker/metadata-action aracının ne işe yaradığını anlamak için resmi GitHub reposunun ana sayfasını inceleyelim. Bu kaynak, eylemin temel amacını ve nasıl kullanılacağına dair genel bir bakış sunar.
Sayfanın başındaki "About" bölümünü okuyarak bu eylemin ne için kullanıldığını kavrayın. Temel amaç, Git referanslarından ve GitHub olaylarından Docker için metadata (etiketler, etiketler) çıkarmaktır.
İş Akışına Versiyonlamayı Entegre Etme
Şimdi, önceki derste oluşturduğumuz build-and-push işini, commit SHA'sı ile etiketleme yapacak şekilde güncelleyelim. Bu iki adımlı bir süreçtir:
- Metadata (etiketler) üreten
docker/metadata-actionadımını eklemek. docker/build-push-actionadımını, bu üretilen etiketleri kullanacak şekilde güncellemek.
Adım 1: Metadata Çıkarma Adımını Ekleme
build-and-push işinizin içine, login-action adımından sonra ve build-push-action adımından önce yeni bir adım ekleyin.
# .github/workflows/main.yml dosyanızdaki 'build-and-push' job'una ekleyin
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# YENİ ADIM: Docker metadata'sını çıkar
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ secrets.DOCKER_USERNAME }}/pyspark-etl
tags: |
type=sha
Bu yeni adımın detayları:
id: meta: Bu adıma "meta" adında bir kimlik atar. Bu, sonraki adımlarda bu adımın çıktılarına (outputs) referans vermemizi sağlar.images: ...: Etiketlerin hangi imaj adı için üretileceğini belirtir.tags: type=sha: Bu en kritik kısımdır.metadata-action'a Git commit SHA'sını kullanarak bir etiket oluşturmasını söyler. Varsayılan olarak,sha-önekiyle birlikte 7 karakterlik kısa bir SHA üretir (örneğin,sha-abcdef1).
Bu type=sha özelliğinin nasıl çalıştığını daha detaylı anlamak için metadata-action'ın dokümantasyonuna göz atabilirsiniz.
docker/metadata-action - GitHub
Şimdi metadata-action'ın en önemli girdisi olan tags'ı ve özellikle type=sha'nın nasıl çalıştığını inceleyelim. Bu, öğrenme hedefimizle doğrudan ilgilidir.
Sayfada tags input başlığını bulun ve okuyun. Ardından, type=sha alt başlığına odaklanın. Bu bölüm, SHA etiketlerinin nasıl oluşturulduğunu, long formatının nasıl kullanılacağını ve prefix'in ne anlama geldiğini açıklar.
Adım 2: Build ve Push Adımını Güncelleme
Şimdi docker/build-push-action adımını, meta adımının ürettiği etiketleri kullanacak şekilde değiştirmeliyiz. Artık etiketi manuel olarak (:latest) yazmayacağız.
Eski Hali:
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
# ... diğer parametreler
tags: ${{ secrets.DOCKER_USERNAME }}/pyspark-etl:latest
Yeni Hali:
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Değişikliklerin açıklaması:
tags: ${{ steps.meta.outputs.tags }}: Bu ifade,id'simetaolan adımın (steps.meta) çıktılarına (outputs) erişir vetagsadlı çıktıyı alır.metadata-actionbu çıktıya,type=shakuralına göre oluşturduğusha-abcdef1gibi bir değer atar.labels: ${{ steps.meta.outputs.labels }}: İyi bir uygulama olarak,metadata-actiontarafından oluşturulan standart OCI (Open Container Initiative) etiketlerini de imajımıza ekliyoruz. Bu, imaj hakkında sürüm, oluşturulma tarihi gibi ek bilgiler içerir.
Tamamlanmış İş Akışı ve Uygulama
Güncellenmiş build-and-push işiniz aşağıdaki gibi görünmelidir. Bu örnek, OneUptime tarafından hazırlanan bir blog yazısındaki en iyi uygulamaları yansıtmaktadır ve bizim projemiz için de geçerlidir.
How to Build and Push Docker Images with GitHub Actions
Bu blog yazısı, bizim yaptığımıza çok benzer bir şekilde, metadata-action kullanarak bir GitHub Actions iş akışının nasıl oluşturulacağını gösteren eksiksiz bir örnek sunar.
Makaledeki "Basic Build and Push to GHCR" başlığı altındaki YAML kod bloğunu inceleyin. Özellikle "Step 4: Generate tags and labels from Git metadata" ve "Step 5: Build and push the Docker image" adımlarının bizim yaptığımız değişikliklerle nasıl örtüştüğüne dikkat edin. Ayrıca, "Tagging Strategy" tablosu, farklı etiket türlerinin kullanım amaçlarını özetlemektedir.
Güncellenmiş build-and-push Job:
build-and-push:
runs-on: ubuntu-latest
needs: test-and-lint # Önceki job'unuzun adıyla değiştirin
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ secrets.DOCKER_USERNAME }}/pyspark-etl
tags: |
type=sha
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Sıra Sizde:
- Projenizin
.github/workflows/main.ymldosyasını yukarıdaki gibi güncelleyin. - Bu değişikliği commit'leyip GitHub repository'nize push edin.
- Repository'nizin Actions sekmesine gidin ve iş akışının çalışmasını izleyin.
- İş akışı başarıyla tamamlandıktan sonra Docker Hub hesabınıza gidin.
pyspark-etlrepository'nizdelatestyerine, az önce yaptığınız commit'in SHA'sı ile etiketlenmiş yeni bir imaj görmelisiniz.
Sonuç
Tebrikler! Artık CI işlem hattınız, her kod değişikliği için benzersiz ve izlenebilir bir Docker imajı üretiyor. latest etiketinin belirsizliğinden kurtulup, hangi kodun hangi imajda olduğunu tam olarak bildiğiniz sağlam bir sürümleme sistemine geçiş yaptınız.
Temel Çıkarımlar:
latestetiketi üretim ortamlarında izlenebilirlik sorunları yaratır ve kullanılmamalıdır.- Git commit SHA'ları, kod ve Docker imajları arasında değişmez bir sürüm bağlantısı kurmak için mükemmel bir yöntemdir.
docker/metadata-action, GitHub Actions'da Docker etiketlerini ve yaftalarını Git bağlamından dinamik olarak oluşturmak için standart bir araçtır.- GitHub Actions'daki
idvesteps.<id>.outputsmekanizması, adımlar arasında veri aktarımı için kullanılır.
Gelecek Dersin Önizlemesi:
Şu ana kadar CI/CD işlem hattımız kodu test ediyor, imajı oluşturuyor ve versiyonlayarak bir registry'e yüklüyor. Ancak bu imaj henüz hiçbir yerde çalışmıyor. Bir sonraki dersimizde, bu container'ize edilmiş PySpark işini bir Kubernetes kümesinde çalıştırmak için gereken manifest dosyasını (Kubernetes Job) yazmayı öğreneceğiz. Bu, Sürekli Dağıtım'a (Continuous Deployment) giden yolda ilk adımımız olacak.