Joburile de imagine se calcă reciproc la autentificarea în registry
Cele două joburi care construiesc imaginile de container rulează în paralel pe
același runner shell și își calcă reciproc autentificarea la registry. Când se
întâmplă, al doilea docker push e respins, jobul pică, iar deploy-ul nu mai
rulează. Efectul practic: o livrare corectă se oprește la jumătate și cere
intervenție manuală, fără ca nimic din cod să fie greșit.
Ce am găsit
Pipeline-ul 7983 pe main, commit 08a8423e:
17771 success package build:backend-image
17772 failed package build:frontend-image
17773 skipped deploy deploy:production
Din jurnalul jobului picat, la docker push:
unauthorized: HTTP Basic: Access denied. The provided password or token is
incorrect or your account has 2FA enabled ...
Imaginea se construise complet — nginx -t trecuse, stratul fusese exportat și
etichetat. A picat exact la împingerea în registry.
Reluat singur, jobul 17776 a trecut din prima, fără nicio schimbare de cod, iar
deploy-ul a pornit apoi normal. Deci nu e o problemă de credențiale greșite, ci
de moment.
Cauza, din configurație: ambele joburi rulează pe eticheta hyperice-shell —
runner shell, nu docker — și fac fiecare docker login cu tokenul propriu de job
(.gitlab-ci.yml:116 și :136). Pe un runner shell, docker login scrie în
aceeași ~/.docker/config.json a utilizatorului. Cele două joburi din stadiul
package pornesc simultan: al doilea login suprascrie credențialele primului,
iar când primul job se termină GitLab îi revocă tokenul — care e chiar cel rămas
în fișier. Al doilea push pleacă atunci cu un token revocat.
Se manifestă intermitent, pentru că depinde de care job termină primul și de cât durează build-ul fiecăruia.
De făcut
-
Dă fiecărui job propriul director de configurație docker, ca cele două să nu mai scrie în același fișier: DOCKER_CONFIGpe un cale din directorul de build al jobului, setat învariablesla ambele joburi din stadiulpackage. -
Alternativă, dacă prima nu e destul: resource_groupcomun pe cele două joburi, ca să nu mai ruleze niciodată în paralel. Costă timp de pipeline, deci e a doua opțiune, nu prima. -
Verifică dacă mai există joburi care fac docker loginpe același runner (deploy:*,smtp:config:*) și care ar putea intra în aceeași cursă.
Criteriu de acceptare
- Zece pipeline-uri consecutive pe
mainsaudeveloptrec fără reluare manuală a vreunui job din stadiulpackage. - Cele două joburi continuă să ruleze în paralel (nu se rezolvă prin serializare, dacă prima variantă e destulă).
De reținut până atunci
Un build:*-image picat cu unauthorized la push NU e o problemă de cod:
se reia jobul, iar pipeline-ul continuă singur cu deploy-ul. Producția nu e
atinsă, pentru că stadiul de deploy vine după cel de package.
Orice diff care atinge .gitlab-ci.yml lasă MR-ul fără pipeline; schimbarea se
face în MR propriu, apoi se pornește un pipeline manual.