GitHub Actions'ta Docker imajı nasıl yayınlanır?
Beceri rehberi

GitHub Actions'ta Docker imajı nasıl yayınlanır?

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

GitHub Actions ile Docker imajını derleyip GitHub Container Registry'ye göndermenin adımları: izinler, login, etiketleme, build-push ve imaj doğrulama.

Pipeline'ın amacı ve genel akışı

Docker imajını elle derleyip registry'ye göndermek, kimin hangi sürümü ne zaman gönderdiğini izlenemez kılar. GitHub Actions ile bu işlem her sürüm etiketi ya da ana dala birleştirme sonrasında otomatik çalışır; imaj her zaman deponun belirli bir commit'inden üretilir.

Genel akış şöyledir: kodu al, registry'ye giriş yap, imaj etiketlerini ve etiket bilgilerini (label) üret, imajı derle ve gönder, isteğe bağlı olarak imaj için bir kaynak doğrulama kaydı (attestation) oluştur. Bu akışta resmî Docker action'ları kullanılır: docker/login-action, docker/metadata-action ve docker/build-push-action. Registry olarak GitHub Container Registry (ghcr.io) en kolay başlangıçtır; Docker Hub ya da bulut sağlayıcı registry'leri de aynı mantıkla kullanılır.

İzinler ve kimlik doğrulama

GitHub Container Registry'ye imaj göndermek için işe packages: write ve contents: read izinleri verilir. İmaj için kaynak doğrulama kaydı da oluşturulacaksa attestations: write ve id-token: write izinleri eklenir. İzinleri iş düzeyinde en az yetkiyle tanımlamak, ele geçirilmiş bir adımın verebileceği zararı sınırlar.

Giriş için docker/login-action kullanılır: registry alanına ghcr.io, kullanıcı adı olarak github.actor, parola olarak da secrets.GITHUB_TOKEN verilir. GITHUB_TOKEN her çalıştırmada otomatik üretilir; elle bir parola saklamaya gerek kalmaz. Docker Hub veya başka bir registry için ise erişim anahtarı depo ya da ortam gizli bilgisi olarak saklanır ve metne ya da kaynak koda asla yazılmaz.

Pull request'lerde, özellikle fork'lardan gelenlerde gizli bilgiler varsayılan olarak verilmez; bu yüzden gönderme adımı genellikle yalnızca ana dal ve etiket olaylarında çalıştırılır, pull request'te ise sadece derleme denemesi yapılır.

Etiketleme stratejisi

İmaj etiketi, hangi sürümün çalıştığını anlamanın tek yoludur. docker/metadata-action, depo adından, dal ya da git etiketinden ve commit bilgisinden etiket ve label'ları otomatik üretir. Step'e bir kimlik (id) verip çıktıları sonraki build adımına bağlarsınız: tags ve labels çıktıları.

Yaygın bir strateji şudur:

  • Sürüm etiketi git etiketinden türetilir (örneğin bir sürüm yayımlandığında).
  • Dal adı etiketi, ana daldaki en son derlemeyi gösterir.
  • Commit özeti (sha) etiketi, tam izlenebilirlik sağlar.
  • 'latest' etiketi yalnızca bilinçli olarak, kararlı sürümde güncellenir.

Üretim ortamının 'latest' yerine değişmez bir etiket ya da imaj özeti (digest) ile dağıtım yapması, geri dönüşü ve hata ayıklamayı kolaylaştırır. Hangi etiketin hangi commit'ten çıktığını imaj label'larında tutmak, olay anında kaynağa hızlı ulaşmayı sağlar.

Derleme ve gönderme adımı

docker/build-push-action, Dockerfile'dan imajı derler ve push seçeneği açıksa registry'ye gönderir. Temel girdiler context (derleme bağlamı, çoğu zaman depo kökü), push (gönderme açık mı), tags ve labels'tır. Metadata step'inin çıktılarını doğrudan buraya bağlarsınız. Step'e bir kimlik verirseniz çıktıdaki imaj özetine sonraki adımlarda ulaşabilirsiniz.

Örneğin bir Node servisi için akış: depo çekilir, ghcr.io'ya giriş yapılır, metadata ile etiketler üretilir, build-push ile imaj gönderilir. Pull request'te push kapatılarak yalnızca derlemenin başarılı olup olmadığı kontrol edilir.

Derleme hızı için Buildx ve derleme önbelleği kullanılabilir; Buildx kurulum adımı iş akışına eklenir. Çok katmanlı (multi-stage) Dockerfile, hem imajı küçültür hem de önbellekten daha iyi yararlanır. Önbellek ve hızlandırma konusu ayrı bir başlıktır.

İmaj güvenliği ve kaynak doğrulama

Yayınlanan imajın hangi depodan, hangi workflow ile üretildiğini kanıtlamak güvenlik açısından değerlidir. GitHub'ın artifact attestation özelliği, imaj özetine bağlı imzalı bir kaynak kaydı üretir; subject-name olarak imaj adı, subject-digest olarak build adımının çıktısındaki özet verilir. Tüketen taraf bu kaydı doğrulayarak imajın gerçekten bu pipeline'dan çıktığını teyit edebilir.

Bunun yanında temel güvenlik önlemleri şunlardır: base imajı güvenilir kaynaktan ve sabitlenmiş sürümle almak, imajı gönderim öncesinde güvenlik açığı tarayıcısından geçirmek, imaja gizli bilgi ya da .env dosyası kopyalamamak, uygulamayı root olmayan kullanıcıyla çalıştırmak ve harici action'ları sürüme sabitlemek.

Birden çok registry'ye göndermek gerekiyorsa her biri için ayrı login adımı eklenir ve metadata adımında imajlar listelenir; ancak imaj özeti registry'ler arasında farklı çıkabilir, bu da doğrulamayı zorlaştırır. Tek bir özet için önce bir registry'ye gönderip diğerlerine kopyalama yöntemi önerilir.

Pipeline'ı üretim akışına bağlamak

İmaj yayınlama, dağıtım zincirinin ortasındadır. Test geçmeden imaj gönderilmemeli: workflow'da önce test işi, ardından imaj işi gelmeli ve imaj işi needs ile teste bağlanmalıdır. Gönderilen imaj daha sonra staging ve üretim ortamlarına dağıtılır; her ortamda aynı imajın kullanılması, 'testte çalıştı ama üretimde bozuldu' sorununu azaltır.

Sürüm yayımlama olayına bağlanmış bir workflow, release oluşturulduğunda imajı otomatik olarak etiketleyip gönderebilir. Ana dala her birleştirmede yayınlamak ise sürekli teslimat yaklaşımına uygundur. Hangisini seçeceğiniz, ekibin yayın ritmine bağlıdır.

Eski imajların registry'de birikmesini önlemek için saklama (retention) politikası tanımlayın. Aksi halde depolama büyür ve hangi imajın canlıda kullanıldığı karışır.

Sık yapılan hatalar

  • GITHUB_TOKEN için packages: write izni vermeyi unutmak; gönderme adımı izin hatasıyla durur.
  • Registry parolasını veya erişim anahtarını workflow dosyasına yazmak. Daima gizli bilgi olarak saklanmalıdır.
  • Pull request'te de imaj göndermeye çalışmak; fork kaynaklı çalıştırmalarda gizli bilgi olmadığı için başarısız olur.
  • Her imajı 'latest' etiketiyle göndermek; hangi sürümün canlıda olduğu belirsizleşir.
  • Dockerfile'da katman sırasını düşünmeden yazmak; önbellek hiç kullanılmaz ve her derleme uzun sürer.
  • İmaj içine gizli bilgi kopyalamak; imaj katmanlarında kalıcı olarak görünür.
  • Test başarısızken imaj yayınlayan bir workflow kurmak.

Bu beceriyi Mindset programlarında nerede çalışırsınız?

CI/CD Pipeline Tasarımı (GitHub Actions) eğitiminde Konteyner ve Image Yönetimi modülü bu konuya doğrudan karşılık gelir; Sürekli Entegrasyon Boru Hattı ve Çok Ortamlı Deployment Stratejileri modülleri imaj yayınlamanın öncesini ve sonrasını tamamlar. Güvenlik ve Uyumluluk Entegrasyonu modülü ise imaj tarama ve güvenlik adımlarını kapsar.

Temel Docker Eğitimi ise konteyner kavramlarından başlayan bir temel sunar: Docker'a Giriş ve Temel Kavramlar, Docker Image ve Container Yönetimi, Dockerfile ile Özel Image Oluşturma, Docker Volumes ve Network Yönetimi, Docker Compose ile Çoklu Servis Yönetimi ve Docker ve CI/CD Entegrasyonu modülleri. Docker'a yeni olan geliştiriciler için sıralı bir yol olarak önce temel eğitim, ardından pipeline eğitimi düşünülebilir.

İlgili Mindset programı

CI/CD Pipeline Tasarımı (GitHub Actions)

Sık sorulanlar

Sık sorulan sorular

GitHub Container Registry mi Docker Hub mı kullanmalıyım?

Kod GitHub'daysa GitHub Container Registry kurulumu en basit seçenektir: giriş için ek parola gerekmez, GITHUB_TOKEN yeterlidir ve imaj depoyla ilişkilendirilir. Docker Hub geniş kamuya açık dağıtım için yaygındır. Kuruluş politikası, erişim yönetimi ve maliyet seçimi belirler.

Pull request'lerde imaj göndermeli miyim?

Genellikle hayır. Pull request'te push kapatılıp yalnızca derlemenin başarılı olduğu doğrulanır. Fork'lardan gelen çalıştırmalarda gizli bilgi olmadığı için gönderme zaten başarısız olur. Gönderme adımını ana dal ve sürüm etiketi olaylarına bağlamak daha güvenli ve düzenlidir.

İmaj etiketlerini nasıl yönetmeliyim?

docker/metadata-action ile sürüm, dal ve commit özeti etiketlerini otomatik üretin. Üretim dağıtımında 'latest' yerine değişmez bir sürüm etiketi veya imaj özeti kullanın. Böylece hangi sürümün canlıda olduğu bellidir ve gerektiğinde önceki sürüme dönmek kolaylaşır.

Derleme çok uzun sürüyor, ne yapabilirim?

Dockerfile'da sık değişen komutları sona koyup katman önbelleğinden yararlanın, çok katmanlı derleme kullanın, Buildx ile derleme önbelleğini etkinleştirin ve gereksiz dosyaları .dockerignore ile dışarıda bırakın. Böylece değişmeyen bağımlılık katmanları her seferinde yeniden üretilmez.

İmajın güvenliğini nasıl artırırım?

Güvenilir ve sabitlenmiş bir base imaj kullanın, gönderim öncesinde güvenlik açığı taraması yapın, imaja gizli bilgi koymayın, uygulamayı root olmayan kullanıcıyla çalıştırın ve mümkünse kaynak doğrulama kaydı (attestation) üretin. Action'ları sürüme sabitlemek de zincir güvenliğini artırır.

GitHub Actions ile Docker İmajı Build ve Push