Log Olmadan Build Başarısız Oldu: Çıktı Nasıl Alınır?
Log olmadan başarısız olan bir build, hatanın build işleminiz başlamadan önce gerçekleştiği anlamına gelir. Bunun gerçekleştiği dört aşamayı, bu aşamaları nasıl ayırt edeceğinizi ve her birinden nasıl çıktı alacağınızı öğrenin.
"Build failed." Stack trace yok, compiler hatası yok, hiç çıktı yok. Log olmadan başarısız olan bir build, bir platformun üretebileceği en az işe yarar mesajdır. Ancak genellikle anlamaya değer, belirli bir duruma işaret eder: hata, log üreten işlem başlamadan önce gerçekleşmiştir.
Build tek bir adımdan oluşmaz. Dört aşaması vardır ve her biri farklı şekilde başarısız olur.
Dört aşama
1. Kaynak kodun alınması. Platform, repository'nizi bir ref üzerindeki hâliyle clone eder. 2. Build'in hazırlanması. Nasıl build edileceğini belirler: Dockerfile, buildpack veya algılanan bir framework. 3. Build'in çalıştırılması. Komutlarınız çalışır. Beklediğiniz çıktıyı üreten tek aşama budur. 4. Paketleme. Sonuç, çalıştırılabilir bir image'a dönüştürülür.
Hiç log yoksa hata 1. veya 2. aşamadadır. Build'iniz hiç çalışmamıştır; dolayısıyla herhangi bir çıktı üretmiş olamaz.
1. aşama: kodunuza hiç ulaşılamadı
Belirtiler tamamen sessizlik ve hızlı bir hatadır; genellikle on beş saniyeden kısa sürer.
En yaygın nedenler, görülme sırasına göre:
- Branch mevcut değil.
masterbranch'inde deployment yapacak şekilde yapılandırılmış bir service, repositorymainolarak yeniden adlandırıldığında anında başarısız olur ve neredeyse hiçbir açıklama sunmaz. - Erişim kaldırılmış. Geçen ay çalışan token veya app installation kaldırılmıştır ya da repository, yetkinin artık geçerli olmadığı başka bir organisation'a taşınmıştır.
- Repository private ve bağlantı geçersiz hâle gelmiş. Yukarıdaki durumla aynıdır; platform 403 yerine 404 alır, çünkü Git provider'ları göremediğiniz private repository'ler için bunu döndürür.
- Bir submodule alınamıyor. Ana repository clone edilir, ancak SSH URL kullanan bir submodule başarısız olur; çünkü build environment'ta bu submodule için key yoktur.
Hızlı kontrol: Platform, başarısız deployment için bir commit hash gösteriyor mu? Göstermiyorsa kodunuza hiç ulaşamamıştır ve Dockerfile'ınızdaki hiçbir şey önemli değildir.
2. aşama: nasıl build edeceğini bilmiyor
Bu aşama da sessizdir, çünkü henüz herhangi bir build komutu seçilmemiştir.
- Config'in belirttiği yerde Dockerfile yok.
dockerfilePath, taşınmış bir path'i gösteriyor olabilir. - Root'u olmayan bir monorepo. Platform repository root'una bakıyor, ancak service'iniz
apps/apiiçinde bulunuyor. - Detection hiçbir şey bulamadı. Tanınan bir manifest yok, dolayısıyla hiçbir buildpack eşleşmedi.
- Bir Dockerfile parse edilemiyor. 1. satırdaki syntax error, herhangi bir layer çalışmadan önce işlemi başarısız kılar.
3. aşama: logların bulunduğu yer burasıdır
Aniden kesilen kısmi bir çıktı görüyorsanız 3. aşamadasınız ve en yaygın iki neden koddan çok resource sorunlarıdır:
Bellek yetersizliği. OOM reaper tarafından sonlandırılan bir build, bunu açıklayan herhangi bir çıktı yazamaz. Log, adımın ortasında öylece kesilir. TypeScript, webpack ve Vite build'leri büyük codebase'lerde bu sorunla düzenli olarak karşılaşır. Bunun göstergesi, aynı commit'in daha fazla belleğe sahip olan laptop'ınızda sorunsuz build edilmesidir.
Timeout. Platformun limitini aşan bir build sonlandırılır. Belirti aynıdır: çıktı tamamlanmak yerine kesilir.
Hata yeterince erken gerçekleşirse her ikisi de "log yok" gibi görünür.
4. aşama: build edildi ancak paketlenemiyor
Nadir görülen ve belirli bir durumdur: build başarılı olmuş, ancak artefact hatalıdır. CMD veya ENTRYPOINT içermeyen bir image, architecture mismatch veya platform limitinin üzerinde bir image buna örnektir.
Teşhis sırası
# Is there a commit hash? If not, stage 1.
dockup deployments my-project/my-api --json
# Build logs of the latest deployment, streamed as it goes
dockup logs my-project/my-api --build --follow
# The full record, including which stage took how long
dockup status my-project/my-api --json
Son çıktıda yer alan stageTimings, hatanın yerini belirlemenin en hızlı yoludur. Clone için 0,4 saniye harcayıp ardından stage 1'de failed durumuyla sonlanan bir deployment söz konusuysa sorun stage 1'dedir. Build için doksan saniye harcayıp ardından duran bir deployment ise stage 3 problemidir; büyük olasılıkla bellek sorunudur.
Hiç çıktı yokken çıktı alma
Çaba düzeyine göre sıralanmış üç teknik:
Kısıtı local ortamda yeniden oluşturun. "Benim makinemde build oluyor mu?" diye bakmayın; builder'ın sahip olduğu bellekle build edin:
docker build --memory=2g --memory-swap=2g -t test .
Bu işlem hatayı yeniden oluşturuyorsa sorunu buldunuz; gizemli bir durum değil, bellek sorunudur.
Build'inizi daha ayrıntılı hâle getirin. Çoğu build tool'u, kendisini sonlandırmak üzere olan durum hakkında varsayılan olarak sessizdir.
# Print progress so a truncated log still shows where it stopped
RUN npm ci --loglevel verbose
RUN NODE_OPTIONS="--max-old-space-size=3072" npm run build
Bu NODE_OPTIONS satırını tek başına denemeye değer. Sessizce sonlanan bir Node build'i çoğu zaman bir heap limitine takılır ve bu limiti yükseltmek, hiç diagnostic üretmeyen build'leri düzeltir.
Dockerfile'ı bisect edin. Başarısız olan adımdan sonraki her şeyi comment out edin ve RUN echo "reached step N" marker'larını ekleyin. İlkel bir yöntemdir, ancak başka hiçbir şey işe yaramadığında çalışır.
Bu tür sorunların azalmasını sağlayanlar
Herhangi bir debugging tekniğinden daha önemli olan iki şey vardır.
Özetlenmiş loglar yerine streaming loglar. Çıktı yalnızca build tamamlandıktan sonra görünüyorsa, sonlandırılan bir build hiçbir şey üretmez; çünkü özet en sonda yazılır. Streaming sayesinde build sonlandığında elinizde, sonlandığı ana kadar üretilen log bulunur.
dockup logs my-project/my-api --build --follow
Adlandırılmış ve süreleri ölçülen aşamalar. "Build failed" tek bir bilgi bitidir. "Clone: 0.4s, build: failed after 94s" ifadesi, yukarıdaki dört nedenden üçünü başka hiçbir şey okumadan elemenize yeter.
Sık sorulan sorular
Build'im neden hiç log üretmiyor? Çünkü build komutlarınız çalışmadan önce başarısız oldu; genellikle kaynak kod alınırken veya nasıl build edileceği belirlenirken. Bu aşamaların hiçbiri build çıktısı üretmez.
Local'de build oluyor da platformda neden olmuyor?
En yaygın neden bellektir. Sizin makinenizde builder'dan daha fazla bellek vardır. Başka bir yere bakmadan önce doğrulamak için docker build --memory=2g ile yeniden deneyin.
Adımın ortasında duran bir log ne anlama gelir? Process normal şekilde çıkmak yerine sonlandırılmıştır. İki aday, bellek yetersizliği ve build timeout'ıdır. OOM killer, process'in kendini açıklamasına fırsat vermez.
Dockerfile'a ihtiyacım var mı? Her zaman değil; platformlar yaygın project type'larını algılayabilir ve Dockerfile olmadan build edebilir. Ancak detection'ın başarısız olması da sessiz, logsuz bir hatadır. Bu nedenle açıkça belirtilmiş bir Dockerfile, belirsizliklerin önemli bir bölümünü ortadan kaldırır.
