Sestavení selhalo bez logů: Jak získat výstup
Když sestavení selže bez logů, znamená to, že k selhání došlo ještě před spuštěním samotného sestavení. Zjistěte, ve kterých čtyřech fázích k tomu může dojít, jak je od sebe rozlišit a jak získat výstup z každé z nich.
„Sestavení selhalo.“ Žádný stack trace, žádná chyba kompilátoru, vůbec žádný výstup. Sestavení, které selhalo bez logů, je nejméně užitečná zpráva, jakou může platforma zobrazit. Obvykle ale znamená něco konkrétního, čemu stojí za to porozumět: k selhání došlo ještě před spuštěním komponenty, která vytváří logy.
Sestavení není jeden krok. Skládá se ze čtyř fází a každá selhává jiným způsobem.
Čtyři fáze
1. Načtení zdrojového kódu. Platforma naklonuje váš repozitář na konkrétní ref. 2. Příprava sestavení. Zjišťuje, jak sestavení provést — pomocí Dockerfile, buildpacku nebo detekovaného frameworku. 3. Spuštění sestavení. Provedou se vaše příkazy. To je jediná fáze, která vytváří výstup, který očekáváte. 4. Zabalení. Výsledek se převede na image, který lze spustit.
Pokud nemáte vůbec žádné logy, k selhání došlo ve fázi 1 nebo 2. Sestavení se nikdy nespustilo, takže nemohlo nic vypsat.
Fáze 1: k vašemu kódu se platforma nikdy nedostala
Projevem je naprosté ticho a rychlé selhání — obvykle do patnácti sekund.
Nejčastější příčiny v pořadí:
- Větev neexistuje. Služba je nakonfigurovaná pro nasazení větve
master, ale repozitář byl přejmenován namain. Selhání nastane okamžitě a zpráva obvykle nic moc neprozradí. - Přístup byl odebrán. Token nebo instalace aplikace, která ještě minulý měsíc fungovala, byla odstraněna, případně byl repozitář přesunut do organizace, kde již udělené oprávnění neplatí.
- Repozitář je private a připojení přestalo fungovat. Projev je stejný jako výše; platforma dostane odpověď 404 namísto 403, protože právě tak poskytovatelé Git vracejí požadavky na private repozitáře, které nemůžete zobrazit.
- Submodule nelze načíst. Hlavní repozitář se naklonuje, ale submodule používající SSH URL selže, protože build environment nemá potřebný klíč.
Rychlá kontrola: zobrazuje platforma u neúspěšného nasazení hash commitu? Pokud ne, kód se k ní nikdy nedostal a nic ve vašem Dockerfile není relevantní.
Fáze 2: platforma neví, jak sestavení provést
Také bez výstupu, protože zatím nebyl zvolen žádný build příkaz.
- Dockerfile není na místě uvedeném v konfiguraci.
dockerfilePathukazuje na cestu, která se změnila. - Monorepo bez nastaveného kořene. Platforma kontroluje kořen repozitáře, ale vaše služba se nachází v
apps/api. - Detekce nic nenašla. Nebyl nalezen žádný rozpoznaný manifest, takže neodpovídá žádný buildpack.
- Dockerfile se nepodaří parsovat. Syntax error na prvním řádku způsobí selhání ještě před spuštěním jakékoli vrstvy.
Fáze 3: tady logy existují
Pokud se zobrazuje částečný výstup, který se náhle zastaví, jste ve fázi 3. Dvě nejčastější příčiny souvisejí spíše se zdroji než s kódem:
Nedostatek paměti. Sestavení ukončené OOM reaperem už nestihne vypsat, co se stalo. Log se jednoduše zastaví uprostřed kroku. Sestavení TypeScriptu, webpacku a Vite ve velkých codebasech na to narážejí pravidelně. Typickým vodítkem je, že stejný commit se na vašem notebooku sestaví bez problémů, protože má více paměti než builder.
Timeout. Sestavení, které překročí limit platformy, je ukončeno. Projev je stejný: výstup se zastaví, místo aby skončil.
Obojí může vypadat jako „žádné logy“, pokud k selhání dojde dostatečně brzy.
Fáze 4: sestavení proběhlo, ale výsledek nelze zabalit
Vzácný a specifický případ: sestavení proběhlo úspěšně, ale artefakt není správný. Může jít o image bez CMD nebo ENTRYPOINT, nekompatibilní architekturu nebo image příliš velký pro limit platformy.
Pořadí diagnostiky
# 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
stageTimings v posledním výstupu je nejrychlejší způsob, jak určit místo selhání. Nasazení, které strávilo 0,4 sekundy klonováním a pak skončilo jako neúspěšné, selhalo ve fázi 1. Pokud strávilo devadesát sekund sestavováním a potom se zastavilo, jde o problém ve fázi 3, s největší pravděpodobností související s pamětí.
Jak získat výstup, když žádný není
Tři techniky seřazené podle náročnosti:
Reprodukujte omezení lokálně. Nejde o otázku „sestaví se to na mém počítači“, ale o sestavení se stejným množstvím paměti, jaké má builder:
docker build --memory=2g --memory-swap=2g -t test .
Pokud takto selhání reprodukujete, našli jste příčinu — jde o paměť, nikoli o něco tajemného.
Zvyšte množství výstupu ze sestavení. Většina build nástrojů ve výchozím nastavení neposkytuje dost informací o problému, který je za chvíli ukončí.
# 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
Samotný řádek s NODE_OPTIONS stojí za vyzkoušení — sestavení v Node, které skončí bez výstupu, je velmi často omezené velikostí heapu a jeho zvýšení vyřeší sestavení, které předtím neposkytovalo vůbec žádné diagnostické informace.
Proveďte bisekci Dockerfile. Zakomentujte vše za krokem, u kterého selhání nastává, a přidejte značky RUN echo "reached step N". Je to hrubé řešení, ale funguje, když nic jiného nepomůže.
Co pomáhá omezit tento typ problémů
Dvě věci jsou důležitější než jakákoli technika ladění.
Streamování logů místo jejich souhrnného zobrazení. Pokud se výstup zobrazí až po dokončení sestavení, sestavení ukončené násilně nevytvoří nic, protože souhrn se zapisuje až na konci. Při streamování máte k dispozici log až do okamžiku ukončení.
dockup logs my-project/my-api --build --follow
Pojmenované a časované fáze. „Sestavení selhalo“ je jedna informace. „Klonování: 0,4 s, sestavení: selhalo po 94 s“ stačí k vynechání tří ze čtyř výše uvedených příčin, aniž byste museli cokoli dalšího číst.
Často kladené otázky
Proč moje sestavení vůbec nevytváří logy? Protože selhalo ještě před spuštěním vašich build příkazů — obvykle při načítání zdrojového kódu nebo při zjišťování, jak sestavení provést. Ani jedna z těchto fází nevytváří výstup sestavení.
Proč se sestavení lokálně podaří, ale na platformě ne?
Nejčastěji kvůli paměti. Váš počítač jí má více než builder. Spusťte docker build --memory=2g a potvrďte si to, než začnete hledat příčinu jinde.
Co znamená log, který se zastaví uprostřed kroku? Proces byl ukončen, místo aby sám skončil. Nejpravděpodobnějšími kandidáty jsou nedostatek paměti a timeout sestavení. OOM killer přitom procesu nedá šanci, aby svou situaci vysvětlil.
Potřebuji Dockerfile? Ne nutně — platformy dokážou rozpoznat běžné typy projektů a sestavit je i bez něj. Selhání detekce je ale samo o sobě tiché selhání bez logů, takže explicitní Dockerfile odstraní celou skupinu nejasností.
