Indeks dnevnikaDockup / bilješka s terena
Note / build-fails-with-no-logs

Neuspjeli build bez logova: kako dobiti izlaz

Ako je build neuspješno završen bez logova, to znači da je do greške došlo prije pokretanja vašeg builda. Saznajte u koje četiri faze to može nastupiti, kako ih razlikovati i kako dobiti izlaz iz svake od njih.

"Build failed." Bez stack tracea, compiler errora i ikakvog izlaza. Neuspjeli build bez logova najmanje je korisna poruka koju platforma može prikazati i obično znači nešto konkretno što vrijedi razumjeti: do greške je došlo prije pokretanja onoga što stvara logove.

Build nije jedan korak. Ima ih četiri i svaki ne uspijeva na drugačiji način.

Četiri faze

1. Dohvaćanje izvornog koda. Platforma klonira vaš repository na određenom refu. 2. Priprema builda. Određuje kako izvesti build — Dockerfile, buildpack ili prepoznati framework. 3. Pokretanje builda. Izvršavaju se vaše naredbe. To je jedina faza koja stvara izlaz koji očekujete. 4. Pakiranje. Rezultat se pretvara u image koji se može pokrenuti.

Ako uopće nemate logove, do greške je došlo u 1. ili 2. fazi. Vaš build nikad nije pokrenut, pa nije mogao ništa ni ispisati.

1. faza: vaš kod nikad nije dohvaćen

Simptomi su potpuna tišina i brzi neuspjeh — obično za manje od petnaest sekundi.

Uobičajeni uzroci, redom:

  • Branch ne postoji. Service je konfiguriran za deployment brancha master, a repository je preimenovan u main. To ne uspijeva odmah i ne prikazuje gotovo nikakve informacije.
  • Pristup je opozvan. Token ili instalacija aplikacije koji su radili prošli mjesec uklonjeni su ili je repository premješten u organisation na koju se ta dozvola više ne primjenjuje.
  • Repository je privatan, a veza je istekla. Isti obrazac kao gore; platforma dobiva 404 umjesto 403 jer je to ono što Git provideri vraćaju za privatne repositoryje koje ne možete vidjeti.
  • Submodule se ne može dohvatiti. Glavni repository se klonira, ali submodule koji koristi SSH URL ne uspijeva jer build environment nema ključ za njega.

Brza provjera: prikazuje li platforma hash commita za neuspjeli deployment? Ako ga ne prikazuje, kod nikad nije dohvaćen i ništa u vašem Dockerfileu nije relevantno.

2. faza: platforma ne zna kako izvesti build

I ova je faza tiha jer build command još nije odabran.

  • Nema Dockerfilea na mjestu navedenom u konfiguraciji. dockerfilePath upućuje na putanju koja je premještena.
  • Monorepo bez root direktorija. Platforma gleda root repositoryja, a vaš se service nalazi u apps/api.
  • Detekcija nije pronašla ništa. Nema prepoznatog manifesta pa nijedan buildpack nije odgovarao.
  • Dockerfile se ne može parsirati. Sintaksna greška u prvom retku uzrokuje neuspjeh prije pokretanja ijednog layera.

3. faza: ovdje postoje logovi

Ako vidite dio izlaza koji se naglo prekida, nalazite se u 3. fazi, a dva su najčešća uzroka resursi, a ne kod:

Nedostatak memorije. Build koji zaustavi OOM reaper nema priliku ispisati što se dogodilo. Log se jednostavno prekida usred koraka. Buildovi za TypeScript, webpack i Vite na velikim codebaseovima redovito nailaze na to, a znak je da se isti commit na vašem laptopu izgradi bez problema jer on ima više memorije nego builder.

Istek vremena. Build koji prekorači ograničenje platforme se prekida. Isti simptom: izlaz se prekida umjesto da završi.

Oboje izgleda kao "nema logova" ako do greške dođe dovoljno rano.

4. faza: build je uspješan, ali ne može se zapakirati

Rijetko i specifično: build je uspješan, ali artefact nije ispravan. Image bez CMD ili ENTRYPOINT naredbe, nepodudaranje arhitekture ili image koji je prevelik za ograničenje platforme.

Redoslijed dijagnostike

# 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 u tom posljednjem izlazu najbrži je način za lociranje greške. Deployment koji je potrošio 0,4 sekunde na kloniranje, a zatim završio neuspjehom, doživio je grešku u 1. fazi. Onaj koji je devedeset sekundi izvodio build i zatim se zaustavio problem je 3. faze, najvjerojatnije memorije.

Kako dobiti izlaz kada ga nema

Tri tehnike, redom prema zahtjevnosti:

Lokalno reproducirajte ograničenje. Nije dovoljno pitati se "izgrađuje li se na mom računalu" — izgradite ga s istom količinom memorije koju ima builder:

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

Ako time reproducirate grešku, pronašli ste uzrok i riječ je o memoriji, a ne o nečemu misterioznom.

Učinite svoj build detaljnijim. Većina build alata prema zadanim je postavkama škrta s informacijama o onome što će ih zaustaviti.

# 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

Sam redak s NODE_OPTIONS vrijedi isprobati — build za Node koji se nečujno ruši vrlo često doseže ograničenje heapa, a njegovo povećanje rješava buildove koji nisu proizveli nikakvu dijagnostičku poruku.

Bisectajte Dockerfile. Zakomentirajte sve nakon koraka koji ne uspijeva i dodajte oznake RUN echo "reached step N". Grubo je, ali funkcionira kada ništa drugo ne pomaže.

Što smanjuje ovu vrstu problema

Dvije su stvari važnije od bilo koje debugging tehnike.

Streaming logova umjesto sažetih logova. Ako se izlaz prikazuje tek nakon završetka builda, build koji se prekine neće proizvesti ništa jer se sažetak zapisuje na kraju. Streaming znači da pri prekidu imate log do trenutka kada je do njega došlo.

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

Faze s nazivima i mjerenjem vremena. "Build failed" jedna je informacija. "Clone: 0.4s, build: failed after 94s" dovoljno je da preskočite tri od četiri gore navedena uzroka bez čitanja ičega.

Često postavljana pitanja

Zašto moj build uopće ne proizvodi logove? Zato što nije uspio prije pokretanja vaših build naredbi — najčešće pri dohvaćanju izvornog koda ili određivanju načina izgradnje. Nijedna od tih faza ne proizvodi build output.

Zašto se build lokalno izgradi, ali ne i na platformi? Najčešće zbog memorije. Vaše računalo ima više memorije nego builder. Reproducirajte problem naredbom docker build --memory=2g kako biste to potvrdili prije nego što tražite uzrok drugdje.

Što znači log koji se prekida usred koraka? Proces je prekinut, umjesto da je završio rad. Dva su kandidata nedostatak memorije i istek vremena za build, a OOM killer procesu ne daje priliku da objasni što se dogodilo.

Treba li mi Dockerfile? Ne nužno — platforme mogu prepoznati uobičajene vrste projekata i izvesti build bez njega. No neuspjela detekcija sama je po sebi tiha greška bez logova, pa eksplicitni Dockerfile uklanja cijelu skupinu nejasnoća.