Build zlyhal bez logov: ako získať výstup
Ak build zlyhal bez logov, znamená to, že k zlyhaniu došlo ešte pred spustením vášho buildu. Zistite, v ktorých štyroch fázach k tomu dochádza, ako ich odlíšiť a ako získať výstup z každej z nich.
„Build zlyhal.“ Žiadny stack trace, žiadna chyba kompilátora, vôbec žiadny výstup. Build, ktorý zlyhal bez logov, je najmenej užitočná správa, akú môže platforma zobraziť. Zvyčajne však znamená niečo konkrétne, čomu sa oplatí porozumieť: k zlyhaniu došlo predtým, než sa spustila vec, ktorá vytvára logy.
Build nie je jeden krok. Má štyri fázy a každá zlyháva iným spôsobom.
Štyri fázy
1. Načítanie zdrojového kódu. Platforma naklonuje váš repozitár na konkrétnom ref. 2. Príprava buildu. Zistí, ako build vytvoriť — pomocou Dockerfile, buildpacku alebo detegovaného frameworku. 3. Spustenie buildu. Vykonajú sa vaše príkazy. Toto je jediná fáza, ktorá vytvára výstup, ktorý očakávate. 4. Zabalenie. Výsledok sa zmení na spustiteľný image.
Ak nemáte vôbec žiadne logy, k zlyhaniu došlo vo fáze 1 alebo 2. Build sa nikdy nespustil, takže nemohol nič vypísať.
Fáza 1: váš kód sa nikdy nenačítal
Prejavmi sú úplné ticho a rýchle zlyhanie — zvyčajne do pätnástich sekúnd.
Najčastejšie príčiny v poradí:
- Vetev neexistuje. Služba je nakonfigurovaná na deployment vetvy
master, no repozitár bol premenovaný namain. Zlyhá to okamžite a takmer bez vysvetlenia. - Prístup bol odobratý. Token alebo inštalácia aplikácie, ktoré fungovali minulý mesiac, boli odstránené, prípadne bol repozitár presunutý do organizácie, kde už udelenie prístupu neplatí.
- Repozitár je private a pripojenie prestalo fungovať. Priebeh je rovnaký ako vyššie; platforma dostane 404 namiesto 403, pretože presne takúto odpoveď poskytujú Git provideri pri private repozitároch, ktoré nemôžete zobraziť.
- Submodule sa nedá načítať. Hlavný repozitár sa naklonuje, no submodule používajúci SSH URL zlyhá, pretože build environment nemá jeho kľúč.
Rýchla kontrola: zobrazuje platforma pri neúspešnom deploymente hash commitu? Ak nie, kód sa nikdy nenačítal a nič vo vašom Dockerfile nie je relevantné.
Fáza 2: platforma nevie, ako build vytvoriť
Aj táto fáza je tichá, pretože zatiaľ nebol zvolený žiadny build príkaz.
- Dockerfile nie je tam, kde ho konfigurácia očakáva.
dockerfilePathukazuje na cestu, ktorá bola presunutá. - Monorepo bez koreňového adresára. Platforma kontroluje koreň repozitára, no vaša služba je v
apps/api. - Detekcia nič nenašla. Neexistuje rozpoznaný manifest, takže sa nenašiel žiadny zodpovedajúci buildpack.
- Dockerfile sa nedá parsovať. Syntaktická chyba na riadku 1 spôsobí zlyhanie ešte pred spustením akejkoľvek vrstvy.
Fáza 3: tu logy existujú
Ak vidíte čiastočný výstup, ktorý sa náhle zastaví, nachádzate sa vo fáze 3. Dve najčastejšie príčiny súvisia skôr so zdrojmi než s kódom:
Nedostatok pamäte. Build ukončený OOM reaperom nestihne vypísať, čo sa stalo. Log sa jednoducho zastaví uprostred kroku. Buildy TypeScriptu, webpacku a Vite na veľkých codebaseoch na tento problém narážajú pravidelne. Typickým znakom je, že ten istý commit sa na vašom notebooku vytvorí bez problémov, pretože má viac pamäte než builder.
Timeout. Build, ktorý prekročí limit platformy, sa ukončí. Príznak je rovnaký: výstup sa zastaví namiesto riadneho ukončenia.
Obe situácie vyzerajú ako „žiadne logy“, ak k zlyhaniu dôjde dostatočne skoro.
Fáza 4: build prebehol, ale nedá sa zabaliť
Ide o zriedkavý a špecifický prípad: build bol úspešný, no artefakt je nesprávny. Môže ísť o image bez CMD alebo ENTRYPOINT, nekompatibilitu architektúry alebo image, ktorý je príliš veľký pre limit platformy.
Poradie 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 poslednom výstupe je najrýchlejší spôsob, ako lokalizovať zlyhanie. Deployment, ktorý strávil 0,4 sekundy klonovaním a potom skončil ako neúspešný vo fáze 1. Deployment, ktorý 90 sekúnd buildoval a potom sa zastavil, signalizuje problém vo fáze 3, s najväčšou pravdepodobnosťou súvisiaci s pamäťou.
Ako získať výstup, keď žiadny nie je
Tri techniky zoradené podľa náročnosti:
Reprodukujte obmedzenie lokálne. Nejde o otázku „funguje build na mojom počítači“ — vytvorte ho s rovnakým množstvom pamäte, aké má builder:
docker build --memory=2g --memory-swap=2g -t test .
Ak sa tým zlyhanie zopakuje, našli ste príčinu. Ide o pamäť, nie o nič záhadné.
Zvýšte množstvo výstupu buildu. Väčšina build nástrojov je v predvolenom nastavení tichá, pokiaľ ide o problém, ktorý ich čoskoro 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
Tento riadok s NODE_OPTIONS sa oplatí vyskúšať aj samostatne — build v Node, ktorý potichu skončí, je veľmi často obmedzený veľkosťou heapu a jej zvýšenie opraví buildy, ktoré nevytvorili vôbec žiadnu diagnostiku.
Rozdeľte Dockerfile metódou bisekcie. Zakomentujte všetko za krokom, pri ktorom zlyhanie nastáva, a pridávajte značky RUN echo "reached step N". Je to síce jednoduché riešenie, ale funguje vtedy, keď nič iné nepomáha.
Čo znižuje výskyt tohto typu problémov
Dôležitejšie než akákoľvek debuggingová technika sú dve veci.
Streamovanie logov namiesto sumarizovaných logov. Ak sa výstup zobrazí až po dokončení buildu, build ukončený počas behu nevytvorí nič, pretože súhrn sa zapisuje až na konci. Pri streamovaní máte v momente zlyhania k dispozícii log až po miesto, v ktorom sa build zastavil.
dockup logs my-project/my-api --build --follow
Pomenované a časované fázy. „Build zlyhal“ je jediná informácia. „Clone: 0,4 s, build: zlyhal po 94 s“ stačí na vylúčenie troch zo štyroch vyššie uvedených príčin bez toho, aby ste museli čokoľvek čítať.
Často kladené otázky
Prečo môj build nevytvára vôbec žiadne logy? Pretože zlyhal ešte pred spustením vašich build príkazov — zvyčajne pri načítavaní zdrojového kódu alebo pri zisťovaní, ako ho vytvoriť. Ani jedna z týchto fáz nevytvára build výstup.
Prečo build funguje lokálne, ale nie na platforme?
Najčastejšie ide o pamäť. Váš počítač jej má viac než builder. Predtým, než začnete hľadať problém inde, overte to pomocou docker build --memory=2g.
Čo znamená log, ktorý sa zastaví uprostred kroku? Proces bol ukončený, namiesto toho, aby skončil vlastnou chybou. Kandidátmi sú nedostatok pamäte alebo timeout buildu. OOM killer nedá procesu príležitosť vysvetliť, čo sa stalo.
Potrebujem Dockerfile? Nie nevyhnutne — platformy dokážu rozpoznať bežné typy projektov a vytvoriť build aj bez neho. Ak však detekcia zlyhá, ide o tiché zlyhanie bez logov, takže explicitný Dockerfile odstraňuje celú skupinu nejasností.
