NaplóindexDockup / terepjegyzet
Note / build-fails-with-no-logs

A build napló nélkül meghiúsult: így szerezhetsz kimenetet

Ha egy build napló nélkül hiúsul meg, az azt jelenti, hogy a hiba még a build elindulása előtt történt. Ismerd meg a négy szakaszt, ahol ez bekövetkezhet, hogyan különböztesd meg őket, és hogyan szerezhetsz kimenetet mindegyikből.

„Build failed.” Nincs stack trace, nincs fordítási hiba, egyáltalán nincs kimenet. A build napló nélkül meghiúsult a platform által adható legkevésbé hasznos hibaüzenet, és általában valami konkrét dolgot jelent, amit érdemes megérteni: a hiba még azelőtt történt, hogy a naplókat előállító folyamat elindult volna.

A build nem egyetlen lépésből áll. Négy szakasza van, és mindegyik másképp hibásodik meg.

A négy szakasz

1. A forrás lekérése. A platform a repositorydat a megadott ref alapján klónozza. 2. A build előkészítése. Meghatározza, hogyan kell buildelni — Dockerfile, buildpack vagy egy felismert framework segítségével. 3. A build futtatása. Lefuttatja a parancsaidat. Csak ez a szakasz állítja elő azt a kimenetet, amelyet vársz. 4. A csomagolás. Az eredményből futtatható image készül.

Ha egyáltalán nincsenek naplók, a hiba az 1. vagy a 2. szakaszban történt. A build el sem indult, ezért semmit sem írhatott ki.

1. szakasz: a kódodhoz hozzá sem jutott

A tünetek teljes csend és gyors hibázás — általában tizenöt másodpercen belül.

A leggyakoribb okok sorrendben:

  • A branch nem létezik. A szolgáltatás úgy van beállítva, hogy a master branchről telepítsen, miközben a repositoryt átnevezték main névre. Ez azonnal meghiúsul, és szinte semmit sem jelez.
  • Visszavonták a hozzáférést. Az előző hónapban még működő token vagy app-installáció megszűnt, vagy a repository egy olyan szervezethez került át, amelyre már nem vonatkozik az engedély.
  • A repository privát, és megszakadt a kapcsolat. Ugyanaz a helyzet, mint az előző esetben; a platform 403 helyett 404-et kap, mert a Git-szolgáltatók ezt adják vissza a nem látható privát repositoryk esetén.
  • Egy submodule nem tölthető le. A fő repository klónozása sikerül, de egy SSH URL-t használó submodule lekérése meghiúsul, mert a buildkörnyezetben nincs hozzá kulcs.

A gyors ellenőrzés: megjelenít a platform commit hash-t a sikertelen telepítésnél? Ha nem, akkor nem jutott hozzá a kódhoz, így a Dockerfile tartalma nem releváns.

2. szakasz: nem tudja, hogyan kell buildelni

Ez a szakasz is csendes, mert még nem választott buildparancsot.

  • Nincs Dockerfile ott, ahol a konfiguráció szerint lennie kellene. A dockerfilePath egy olyan elérési útra mutat, amelyet áthelyeztek.
  • Root nélküli monorepo. A platform a repository gyökerét vizsgálja, miközben a szolgáltatásod az apps/api könyvtárban található.
  • A felismerés nem talált semmit. Nincs felismert manifest, ezért egyetlen buildpack sem illeszkedett.
  • Egy Dockerfile nem elemezhető. Az első sorban lévő szintaktikai hiba még azelőtt hibát okoz, hogy bármelyik layer lefutna.

3. szakasz: itt már vannak naplók

Ha részleges kimenetet látsz, amely hirtelen megszakad, akkor a 3. szakaszban vagy, és a két leggyakoribb ok inkább az erőforrásokhoz, mint a kódhoz kapcsolódik:

Elfogyott a memória. Az OOM reaper által leállított build nem tudja kiírni, mi történt vele. A napló egyszerűen egy lépés közben megszakad. A TypeScript-, webpack- és Vite-buildel gyakran belefutnak ebbe nagy kódbázisok esetén, és árulkodó jel, hogy ugyanaz a commit gond nélkül buildelhető a laptopodon, amely több memóriával rendelkezik, mint a builder.

Időtúllépés. A platform időkorlátját túllépő build leáll. Ugyanaz a tünet: a kimenet megszakad, ahelyett hogy rendesen befejeződne.

Mindkettő „napló nélküli” hibának tűnhet, ha a hiba elég korán következik be.

4. szakasz: a build elkészült, de nem csomagolható

Ritka és egyértelmű eset: a build sikeresen lefutott, de az artifact hibás. Például az image nem tartalmaz CMD vagy ENTRYPOINT utasítást, nem egyezik az architektúra, vagy az image túl nagy a platform korlátjához képest.

A diagnosztika sorrendje

# 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

Az utolsó kimenetben található stageTimings a leggyorsabb módja a hiba helyének meghatározására. Ha egy telepítés 0,4 másodpercet töltött klónozással, majd sikertelenül leállt, akkor a hiba az 1. szakaszban történt. Ha kilencven másodpercet buildeléssel töltött, majd leállt, az a 3. szakasz problémája, legvalószínűbben memóriahiány.

Hogyan szerezz kimenetet, ha nincs

Három technika, a ráfordítás sorrendjében:

Reprodukáld helyben ugyanazt a korlátot. Ne csak azt ellenőrizd, hogy „buildel-e a gépemen” — ugyanazzal a memóriamennyiséggel buildelj, mint amennyivel a builder rendelkezik:

docker build --memory=2g --memory-swap=2g -t test .

Ha ez reprodukálja a hibát, megtaláltad az okát: memóriahiányról van szó, nem valami rejtélyes problémáról.

Tedd beszédesebbé a buildet. A legtöbb buildeszköz alapértelmezés szerint kevés információt ad arról, ami éppen leállítani készül.

# 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

Érdemes önmagában is kipróbálni azt a NODE_OPTIONS sort — a csendben leálló Node-build nagyon gyakran heaplimitet jelez, amelynek megemelése megoldja azokat a buildeket, amelyek egyáltalán nem adtak diagnosztikai kimenetet.

Végezz bináris keresést a Dockerfile-ban. Kommentelj ki mindent a hibát okozó lépés után, majd adj hozzá RUN echo "reached step N" jelölőket. Nem elegáns megoldás, de akkor is működik, amikor semmi más nem.

Mi csökkenti az ilyen problémák előfordulását?

Két dolog fontosabb bármely hibakeresési technikánál.

A naplók streamelése összesített naplók helyett. Ha a kimenet csak a build befejezése után jelenik meg, a leállított build semmit sem ad vissza, mert az összesítés a végén készül el. Streamelés esetén a leálláskor már azt a naplót látod, amely a leállás pillanatáig elkészült.

dockup logs my-project/my-api --build --follow

Elnevezett és időzített szakaszok. A „Build failed” egyetlen bitnyi információ. A „Clone: 0.4s, build: failed after 94s” már elég ahhoz, hogy a fenti négy ok közül hármat kizárj anélkül, hogy bármit el kellene olvasnod.

Gyakran ismételt kérdések

Miért nem készül egyáltalán napló a buildemhez? Mert a buildparancsok futtatása előtt történt hiba — általában a forrás lekérésekor vagy a build módjának meghatározásakor. Egyik szakasz sem állít elő buildkimenetet.

Miért buildelhető helyben, de miért nem a platformon? Leggyakrabban memóriahiány miatt. A gépeden több memória áll rendelkezésre, mint a builderen. A megerősítéshez először próbáld ki a docker build --memory=2g parancsot, és csak utána vizsgáld másutt az okot.

Mit jelent, ha a napló egy lépés közben megszakad? A folyamatot leállították, nem pedig szabályosan kilépett. A két legvalószínűbb ok a memóriahiány és a build időtúllépése, az OOM killer pedig nem ad lehetőséget a folyamatnak arra, hogy megmagyarázza, mi történt.

Szükségem van Dockerfile-ra? Nem feltétlenül — a platformok képesek felismerni a gyakori projekt­típusokat, és Dockerfile nélkül is buildelni. A sikertelen felismerés azonban önmagában is csendes, napló nélküli hibát jelent, ezért egy explicit Dockerfile megszünteti a bizonytalanság egyik teljes kategóriáját.