Case study
Implementacija klijentskog Node.js sajta uz GitLab CI/CD i Kubernetes
Slucaj upotrebe

Studiju za web dizajn isporucena je nova klijentska aplikacija i bilo je potrebno brzo zavrsiti infrastrukturni deo: uzeti postojeci GitLab repozitorijum sa Node.js aplikacijom, izgraditi ga pomocu npm run build i uciniti ga dostupnim kao aktivan sajt na klijentskom domenu, sa CI/CD putem spremnim za buduca izdanja.
Ulazni podaci
- Izvorni kod u GitLab repozitorijumu
- Node.js aplikacija
- Komanda za production build:
npm run build
Isporuka
- Sa radom spreman sajt na klijentskom domenu
- GitLab pipeline koji gradi i objavljuje image aplikacionog kontejnera pri svakom relevantnom push-u
- Kubernetes deployment pripremljen kroz ponovo upotrebljiv pristup zasnovan na Helmu
- SSL automatski izdat tokom deploy-a
Kompletno resenje je isporuceno za oko dva sata.
Korak 1. Priprema aplikacije za isporuku u kontejneru
Prvi zadatak bio je da se aplikacija upakuje na predvidiv i ponovljiv nacin, tako da se isti artefakt moze izgraditi u CI-ju i deploy-ovati u Kubernetes.
Pocetni radni Dockerfile pripremljen je direktno u istom repozitorijumu:
Ovo vec koristi multi-stage build, sto je pravi smer za produkcionu isporuku.
Zasto su multi-stage buildovi vazni

Za Node.js projekte, naivan single-stage image cesto sadrzi:
- kompletan izvorni kod
- zavisnosti potrebne tokom build-a
- development zavisnosti
- cache package menadzera
- privremene build fajlove
To radi, ali stvara nepotrebnu tezinu u produkciji.
Kod multi-stage build-a, teski deo posla se odvija u builder fazi, dok runtime faza dobija samo neophodan izlaz aplikacije. U ovom slucaju, za runtime je potreban samo izgradjeni .output direktorijum. To znaci:
- manji image-i
- brzi push u registry
- brzi pull u Kubernetes-u
- manje zauzeca prostora u container registry-ju
- manja napadacka povrsina u produkciji
Korak 2. Doterivanje Dockerfile-a za CI/CD upotrebu
Nakon prve radne verzije, Dockerfile je optimizovan za predvidivije CI buildove i bolje ponasanje keša.
Finalni optimizovani Dockerfile
| |
Sta je unapredjeno
npm ciumestonpm install
Ovo CI buildove cini deterministickijim jer se zavisnosti instaliraju strogo iz lock fajla.Odvojeni sloj zavisnosti pre kopiranja celog izvornog stabla
To poboljsava ponovnu upotrebu Docker slojeva. Kada developeri menjaju kod aplikacije, ali ne i zavisnosti, sloj za instalaciju zavisnosti moze ostati iz keša.Runtime faza ostaje minimalna
Finalni kontejner sadrzi samo produkcioni runtime i izgradjeni izlaz, ne i kompletno izvorno stablo niti build okruzenje.Cistija runtime komanda
Mala dorada, ali korisna za citljivost i odrzavanje.
Praktican uticaj na velicinu

Glavna dobit nije dosla od male sintaksne dorade, vec od upotrebe multi-stage runtime image-a umesto tipicnog single-stage image-a sa pristupom „sve ukljuceno“.
Za projekat poput ovog, realno poredjenje je:
- naivni single-stage image: ~420 MB
- finalni multi-stage runtime image: ~130 MB
To je smanjenje od oko 290 MB po image-u, odnosno otprilike 69% manje.
Zasto je ovo vazno tokom jedne sedmice
Ovaj tim obicno objavljuje nove verzije nekoliko puta na sat.
Koristeci konzervativan primer:
- 3 push-a po satu
- 8 radnih sati dnevno
- 5 radnih dana nedeljno
To daje:
- 120 image push-eva nedeljno
Uz 290 MB ustede po image-u, nedeljna razlika je:
- 120 × 290 MB = 34,800 MB
- otprilike 34.8 GB manje image podataka
To je samo akumulacija na strani registry-ja pre ciscenja. Ako se garbage collection registry-ja pokrece nedeljno, ta razlika moze ostati sacuvana tokom celog perioda. Drugim recima, naizgled mala optimizacija po build-u brzo postaje desetine gigabajta ustede nedeljno.
Isto smanjenje pomaze i brzini deploy-a, jer svaki push u registry i svaki pull od strane Kubernetes nodova prenosi znatno manje podataka. Cak i pri umerenoj mrežnoj propusnosti, smanjivanje stotina MB po izdanju odmah je primetno tokom cestih izdanja.
Korak 3. Priprema GitLab pipeline-a
Kada je aplikacija bila upakovana u kontejner, sledeci korak bio je da se automatizuju validacija build-a i objavljivanje image-a u GitLab CI/CD.
Trazeni raspored faza bio je:
U ovoj fazi projekta, pipeline je implementiran do build-a i push-a image-a.
Faze deploy i rollback su namerno ostavljene za sledecu fazu, zato sto se samo deploy-ovanje obavljalo kroz Kubernetes + Helmwave.
Primer .gitlab-ci.yml
| |
Sta ovaj pipeline radi

- pokrece lint provere
- pokrece testove ako postoje
- gradi Docker image
- taguje ga commit SHA vrednoscu
- push-uje ga u GitLab container registry
- takodje osvezava
latesttag na glavnoj putanji isporuke
To daje cist build artefakt spreman za Kubernetes deployment.
Korak 4. Primer izlaza pipeline run-a
Ispod je reprezentativan primer izlaza pipeline-a za uspesno izvrsen build-and-push fazni prolaz:
| |
Korak 5. Deploy u Kubernetes uz ponovo upotrebljiv Helm chart
Kada je image vec objavljen u registry-ju, deploy u Kubernetes bio je jednostavan.
Umesto pisanja posebnog chart-a samo za ovaj projekat, deploy je koristio univerzalni Helm chart koji moze da se ponovo upotrebljava kroz mnoge web aplikacije. Ovo je vazno u realnom radu sa klijentima zato sto smanjuje rutinski napor i ubrzava pokretanje buducih projekata.
Zasto ovaj pristup dobro radi
Za tipicnu Node.js web aplikaciju obicno je potrebno prilagoditi samo nekoliko vrednosti:
- image repository
- image tag
- service port
- ingress hostname
- broj replika
- environment varijable, ako su potrebne
Sve ostalo je vec standardizovano u chart-u.
Primer values fajla
| |
Sta je Kubernetes automatski odradio

Pošto je klaster vec imao postavljene uobicajene komponente, vecina posla nije bila manualna:
- Kubernetes je povukao image iz registry-ja
- Ingress je izlozio aplikaciju na target host name-u
- CertManager je zatrazio i izdao SSL sertifikat
- service je usmerio saobracaj ka pod-u aplikacije
Vazan operativni detalj: DNS za domen je vec bio konfiguris an pre nego sto je deploy poceo.
To je znacilo da tokom implementacionog prozora nije bilo cekanja na DNS propagaciju, pa je zivi sajt postao dostupan u roku od nekoliko minuta nakon sto je Kubernetes release primenjen.
Rezultat
Studija je trazila jednostavan ishod: uzeti GitLab repozitorijum sa Node.js aplikacijom i uciniti ga produkciono spremnim, sa aktivnim domenom i CI/CD osnovama.
To je isporuceno kroz kratak i praktican niz koraka:
- pripremljen je production-ready Dockerfile u istom repozitorijumu
- optimizovana je strategija image-a uz multi-stage build
- postavljen je GitLab pipeline za lint, test, build i push u registry
- objavljen je image aplikacije u container registry-ju
- deploy-ovan je u Kubernetes uz ponovo upotrebljiv Helm chart i Helmwave
- izlozen je preko Ingress-a sa automatskim SSL-om iz CertManager-a
Zavrsena isporuka

- aktivan sajt na ciljanom domenu
- aplikacija upakovana u kontejner
- automatizovan build image-a i push pri izmenama koda
- ponovo upotrebljiva Kubernetes konfiguracija za deploy
- SSL omogucen automatski
- skalabilna osnova za buducu deploy/rollback automatizaciju
Vreme isporuke
Ukupno vreme implementacije: oko dva sata.
To je prava vrednost standardizovanog delivery stack-a: kada se Docker, GitLab CI/CD, Kubernetes, Helm, Ingress i CertManager koriste na ponovljiv nacin, cak i nov klijentski projekat moze vrlo brzo da prede od repozitorijuma do zivog domena.