deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Docker Compose pre_start adımları, migrate ve seed pseudo-service deseninin yerini alıyor

Compose 5.3'ün pre_start hook'u, bir servis başlamadan önce kurulum container'larını tamamlanana kadar çalıştırıyor ve böylece sahte servis depends_on desenine son veriyor — öngörülebilir yeniden çalıştırmalarla, tek bir eksikle: başarılı adım çıktıları kayboluyor.

Docker Compose pre_start adımları, migrate ve seed pseudo-service deseninin yerini alıyor

Compose init container'ları kazanıyor

Docker Compose 5.3, Temmuz ayında bir pre_start seçeneği yayınladı ve Docker Desktop o zamandan beri bunu içeriyor; bu bilgi Remdore'un dev.to'da yayımladığı el yordamıyla yapılan bir incelemeye dayanıyor. Bu özellik, bir servisin, servis kendisi başlamadan önce sırayla ve tamamlanana kadar çalışan kurulum container'ları — fiilen init container'lar — tanımlamasına olanak sağlıyor. Yazar, özelliği bir Postgres 18 container'ı ve küçük bir Node uygulamasıyla test etti ve bunun, gerçek hayattaki çoğu Compose dosyasının yıllardır taşıdığı bir çözümün yerini aldığı sonucuna vardı.

Yerine geçtiği çözüm

dev.to yazısında anlatıldığı gibi, üretime yakın her Compose dosyasında gerçekten servis olmayan iki servis bulunma eğiliminde: biri veritabanı migration'larını çalıştıran, diğeri veri tohumlayan (seed) servisler. Bunlar uygulamaya depends_on koşullarıyla, örneğin service_completed_successfully ile zincirlenir, çünkü Compose daha önce "bunu şundan önce çalıştır" demenin bir yolunu sunmuyordu.

Desen işe yarıyor ama sorun çıkarıyor. Her başlatma geride çıkmış (exited) container'lar bırakıyor ve ikinci bir docker compose up -d, migrate ve seed işlerini yeniden çalıştırıyor, çünkü Compose'ın gözünden bunlar yalnızca tekrar çalıştırılması gereken durdurulmuş servislerdir. Yazar, buna karşı olağan savunma olan idempotent seed script'lerinin de aslında insanların yaptıklarını fark etmeyi bıraktığı bir çözüm olduğunu belirtiyor.

pre_start nasıl çalışıyor

Yeni seçenekle migration ve seed adımları, bunlara ihtiyaç duyan servisin üzerinde doğrudan tanımlanıyor. Her adım kendi container'ında sırayla çalışıyor ve servis, yalnızca son adım 0 çıkış koduyla sonlandıktan sonra başlıyor. Bir adım kendi image'ini belirtebiliyor; bir migration böylece uygulama Node image'i kullanırken Postgres image'indeki psql'i çalıştırabiliyor. Image belirtilmeyen adım, servisin image'ini devralıyor. Adımlar ayrıca servisin ağını, ortam değişkenlerini ve mount'larını paylaşıyor; böylece uygulamada tanımlı bir bind mount, farklı bir image çalıştıran bir adımın içinde görülebiliyor ve depends_on koşulları ilk adım çalışmadan önce yerine getiriliyor.

Adım container'ları anonim ve kısa ömürlü: yazar bunları docker events üzerinden gözlemledi; kabaca bir saniye içinde oluşturulup yok ediliyorlar ve rastgele üretilmiş isimlere sahipler. up komutundan sonra docker compose ps -a yalnızca uygulama ve veritabanı container'larını gösteriyor.

--wait ile ölçülen soğuk başlatma süreleri adımsız 3.9 saniye, iki pre_start adımıyla 5.2 saniye ve eski iki servislik desen için 6.7 saniye çıktı — adım başına yaklaşık 0.65 saniye ve yine de yerini aldığı yaklaşımdan daha hızlı.

Adımlar ne zaman yeniden çalışır

Yeniden çalıştırma semantiği, yazarın en çok önem verdiği kısım. İncelemeye göre adımlar; servis container'ı yeniden oluşturulduğunda, adım tanımı değiştiğinde veya önceki çalıştırma başarısız olduğunda yeniden çalışıyor. Zaten çalışan bir stack üzerinde düz bir up hiçbir şey tetiklemiyor; docker compose restart da tetiklemiyor. Servisin üç replikaya ölçeklendirilmesi adımları üç kez değil, bir kez çalıştırdı — yürütme replika başına değil, servis başına.

Belirtime replika başına durum için bir per_replica: true bayrağı dahil edilmiş, ancak Compose 5.5 şu anda bunu yapılandırmada kabul ediyor ama up zamanında açık bir hatayla reddediyor — ve bu hata, dosya çözümlenirken değil, veritabanı zaten sağlıklı şekilde ayağa kalktıktan sonra geliyor.

Depolamayla ilgili bir uyarı: adım container'ları hemen kaybolduğu için tmpfs'e veya anonim bir volume'a yazılan her şey lost oluyor. Adımlar isimli volume'lara veya bind mount'lara yazmalı ya da hiç yazmamalı.

Hata durumunda ne olur

Yazar bir seed adımını 3 çıkış koduyla sonlamaya zorladığında, up -d 1 döndürdü; uygulama Created durumunda kaldı ve hiç başlamadı, uygulamaya bağımlı üçüncü bir servis de Created durumunda kaldı. Başarısız adımın container'ı inceleme için tutuluyor; proje etiketiyle işaretlenmiş durumda ve ona karşı docker logs çalıştırmak adımın çıktısını gösteriyor. docker compose down onu kaldırıyor ve sonraki up, adımın geçtiğini varsaymak yerine onu yeniden çalıştırıyor.

Tek gerçek boşluk

Bir adım başarılı olduğunda çıktısı hiçbir yere gitmiyor — ne up çıktısında, ne attach edildiğinde, ne --progress plain veya --verbose ile, ne de docker compose logs içinde; çünkü onu üreten container çıktıktan saniyeler sonra silinmiş oluyor. Kaç migration'ın uygulandığını bildiren bir migration aracının çıktısı, bir şeyler başarısız olmadığı sürece basitçe kayboluyor. Yazarın çözümü, adımların bir tabloya işaret satırı yazmasıydı ve başarılı hook container'larını kısa süreliğine tutmak küçük bir değişiklik olacağı için bu boşluğun eninde sonunda giderileceğini bekliyorlar. O ana kadar, migration'larının yarısının eski desende kalmasının nedeni bu.

Neden önemli

pre_start, önemsiz olmayan hemen her Compose kurulumunun pseudo-service'lerle taklit ettiği bir şeyi resmileştiriyor ve bu taklidin üç maliyetini ortadan kaldırıyor: geride kalan çıkmış container'lar, sonraki up komutlarında yanlışlıkla yeniden çalıştırmalar ve seed script'lerindeki idempotency çözümleri. Yeniden çalıştırma kuralları öngörülebilir, hatalar bağımlı servisleri temiz biçimde engelliyor ve özellik, Compose'u Kubernetes kullanıcılarının zaten sahip olduğu init-container semantiğine yaklaştırıyor. Başarılı adımların kaybolan çıktısı, kritik migration işlerini buna geçirmeden önce bilinmeye değer tek uyarı. Compose 5.3 veya daha yenisi gereklidir; docker compose version kullanılabilirliği doğrulayacaktır.

  • #docker
  • #docker-compose
  • #containers
  • #devops
  • #orchestration

İlgili yazılar