Docker kontejnerizacija pakuje vašu aplikaciju, njen runtime i sve zavisnosti u prenosivu sliku (image) koja se ponaša potpuno isto na laptopu programera, na CI serveru i u produkciji. Samo to svojstvo uklanja cijelu grupu problema: greške tipa „kod mene radi”, servere koje niko ne smije dirati, uvođenje novog programera koje traje danima i deployment koji zavisi od toga da li se jedna osoba sjeća pravog redoslijeda komandi.
Sadržaj
U CodeWizu dizajniramo i gradimo kontejnerska rješenja za web aplikacije, API-je, pozadinske procese (workere) i baze podataka – od urednog Docker Compose okruženja na jednom VPS-u do orkestracije na više servera sa automatskim rolloutom. Pišemo Dockerfile-ove spremne za produkciju, smanjujemo slike, povezujemo CI/CD i upravljanje tajnama, a na kraju predajemo dokumentaciju koju vaš tim zaista može koristiti.
Usluga je namijenjena startupima koji se pripremaju za rast, agencijama koje vode projekte klijenata sa različitim verzijama PHP-a i Node.js-a, te kompanijama čije starije aplikacije treba prebaciti na novu infrastrukturu bez prepisivanja koda. Ako je deployment kod vas spor, rizičan ili vezan za jedan konkretan server, kontejneri su obično najisplativije rješenje.
Kod teme kontejnerizacija alati otvorenog koda su prvi izbor kada odgovaraju poslu.

Multi-stage Docker buildovi za vitke produkcijske slike
Multi-stage build koristi više FROM instrukcija u jednom Dockerfile-u. Prve faze sadrže kompajlere, package managere i razvojne zavisnosti, a posljednja faza preuzima samo gotove artefakte. Rezultat je produkcijska slika bez alata za build, bez testnih podataka i bez ostataka iz procesa izgradnje.
Kontejnerizacija kreće od sistema koji već radi, a ne od praznog šablona.
Zašto je to važno za vaše poslovanje
- Manje slike se brže preuzimaju i pokreću, pa je deployment kraći, a autoscaling reaguje ranije.
- Manje paketa znači manje ranjivosti koje skeneri prijavljuju i manje alata koje napadač može zloupotrijebiti.
- Jedan Dockerfile opisuje testiranje, build i runtime, tako da se CI i produkcija nikada ne razilaze.
Kako izgleda produkcijski Dockerfile
Ovo je skraćena verzija obrasca koji koristimo za Node.js servis. BuildKit cache mountovi čuvaju npm pakete između buildova, a runtime faza je distroless slika koja se pokreće kao korisnik bez root privilegija:
Rad na temi kontejnerizacija ostaje u vašem repozitoriju i na vašoj infrastrukturi.
# syntax=docker/dockerfile:1
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
FROM deps AS build
COPY . .
RUN npm run build && npm prune --omit=dev
FROM gcr.io/distroless/nodejs22-debian12 AS runtime
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
USER nonroot
EXPOSE 3000
CMD ["dist/server.js"]Isti pristup primjenjujemo na Laravel (faze za Composer i frontend asete, zatim PHP-FPM ili FrankenPHP runtime), Go i Rust (kompajliranje, pa kopiranje statičkog binarnog fajla u scratch), Python (wheel paketi u virtualenv, a u finalnu sliku ide samo virtualenv) i Javu (Maven ili Gradle faza, pa vitki JRE). Dodajemo i imenovane targete, tako da docker build --target test u CI-ju pokreće testove nad potpuno istim zavisnostima kao u produkciji. Zvanični Dockerov vodič za multi-stage buildove detaljno objašnjava sintaksu.
CodeWiz provjerava kontejnerizacija u produkciji, ne samo na demonstraciji.
Optimizacija Docker slika: manje, brže i sigurnije
Optimizacija slika je mjesto gdje većina postojećih Docker okruženja ostavlja lako dostupne dobitke. Slika izgrađena bez razmišljanja na punoj baznoj slici programskog jezika lako pređe 1 GB, dok je ista aplikacija na slim ili distroless osnovi, uz čist build kontekst, često nekoliko puta manja. Optimizujemo u tri pravca: veličina, brzina builda i sigurnost.
Odluke o temi kontejnerizacija vežu se za ograničenje koje stvarno koči poslovanje.
Izbor prave bazne slike
| Bazna slika | Približna veličina | Shell i package manager | Najbolja za | Na šta paziti |
|---|---|---|---|---|
| Debian slim | ~75 MB | Da (apt) | Maksimalnu kompatibilnost i biblioteke koje zahtijevaju glibc | Veća površina za napad |
| Alpine | ispod 10 MB | Da (apk) | Male univerzalne slike | Razlike koje musl libc pravi kod nekih nativnih modula i wheel paketa |
| Distroless | ~2–20 MB plus runtime | Ne | Produkcijski runtime za Node.js, Python, Javu i Go | Za debugging treba debug tag ili ephemeral kontejner |
| scratch | 0 MB | Ne | Statički kompajlirane Go ili Rust binarne fajlove | CA certifikate i podatke o vremenskim zonama morate sami kopirati |
Keširanje slojeva i brzina builda
- Instrukcije redamo od onih koje se najrjeđe mijenjaju ka onima koje se mijenjaju najčešće: sistemski paketi, pa lockfile i instalacija zavisnosti, pa kod aplikacije.
- Strog
.dockerignoreisključuje.git,node_modules, logove, lokalne.envfajlove i testne podatke – manji build kontekst, brži build i nema procurjelih tajni. - Koristimo BuildKit cache mountove za npm, Composer, pip i apt, uz build cache u registryju ili GitHub Actionsu (
--cache-to type=registry), pa CI nikada ne kreće od nule. - Instalaciju i čišćenje radimo u istom
RUNsloju, jer brisanje fajlova u kasnijem sloju ne smanjuje sliku.
Skeniranje, fiksiranje verzija i SBOM
Svaku sliku koju isporučimo skeniramo alatom Trivy u pipelineu: trivy image --severity HIGH,CRITICAL --exit-code 1 zaustavlja build prije nego što ranjiva slika stigne u registry. Bazne slike vežemo za konkretne verzije (ili digest u strožim okruženjima), Renovate ili Dependabot predlažu ažuriranja, a kada to zahtijevaju propisi, generišemo SBOM i potpisujemo slike alatom cosign.
Predaja teme kontejnerizacija uključuje uputstvo koje tim može koristiti.
Docker Compose setup za razvoj i produkciju
Docker Compose opisuje aplikaciju od više kontejnera – aplikaciju, bazu, cache, queue workera, reverse proxy – u jednom deklarativnom fajlu compose.yaml. Mnogim firmama dobro složen Compose na jednom serveru je sva infrastruktura koja im treba, dok je drugima to lokalno razvojno okruženje koje vjerno prati veći produkcijski klaster.
Za kontejnerizacija CodeWiz prvo mjeri ograničenje, pa bira alat.
Jedan fajl, više okruženja
Compose organizujemo tako da osnovni fajl ostaje isti svuda, a razlike žive u override fajlovima i profilima: compose.override.yaml za lokalne bind mountove i debug portove, profili za pomoćne alate poput Mailpita ili Adminera koji se pokreću samo uz --profile dev, te Compose Watch za hot reload bez ručnog rebuilda. Novi programer pokrene jednu komandu i za nekoliko minuta ima cijeli sistem.
services:
app:
build: .
depends_on:
db:
condition: service_healthy
deploy:
resources:
limits: { cpus: "1.0", memory: 512M }
db:
image: postgres:17-alpine
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets: [db_password]
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
mailpit:
image: axllent/mailpit
profiles: [dev]
secrets:
db_password: { file: ./secrets/db_password.txt }
volumes:
pgdata:O čemu vodimo računa
- Healthcheck na svakom servisu i
depends_onsacondition: service_healthy, kako se aplikacija ne bi pokrenula prije nego što baza počne primati konekcije. - Tajne montirane kao fajlovi u
/run/secrets, umjesto običnih varijabli okruženja upisanih u sliku ili commitovanih u Git. - Ograničenja procesora i memorije, restart politike i rotacija logova, kako jedan odbjegli kontejner ne bi oborio cijeli server.
- Imenovani volumeni uz provjerenu proceduru backupa i vraćanja podataka za baze i uploadovane fajlove.
- Reverse proxy (Traefik, Caddy ili Nginx) sa automatskim TLS-om i CI job koji povlači nove slike i restartuje servise uz minimalan prekid rada.
Zvanična Docker Compose dokumentacija je dobra referenca za kompletnu specifikaciju fajla.

Orkestracija kontejnera: Docker Swarm, Kubernetes ili Nomad
Orkestracija kontejnera preuzima stvar kada jedan server više nije dovoljan. Raspoređuje kontejnere po serverima (nodovima), ponovo pokreće one koji padnu, radi postepena ažuriranja, raspoređuje opterećenje i centralno upravlja konfiguracijom i tajnama. Pravi izbor orkestratora mnogo više zavisi od vašeg tima i opterećenja nego od trenutnih trendova.
| Opcija | Težina učenja | Operativni trošak | Kada je najbolji izbor |
|---|---|---|---|
| Docker Compose (jedan server) | Niska | Minimalan | Jedan server, malo do srednje opterećenje, oporavak preko backupa |
| Docker Swarm | Niska | Nizak | Nekoliko nodova, visoka dostupnost bez novih alata – koristi postojeće Compose fajlove |
| Kubernetes (k3s ili managed) | Visoka | Srednji do visok | Mnogo servisa, autoscaling, više timova, bogat ekosistem |
| HashiCorp Nomad | Srednja | Nizak do srednji | Mješovita opterećenja (kontejneri, binarni fajlovi, VM) uz jednostavniji model od Kubernetesa |
Kako biramo
Polazimo od zahtjeva, ne od alata: očekivano opterećenje, ciljana dostupnost, veličina tima i ko će održavati platformu nakon primopredaje. Čest put je Compose na jednom serveru, zatim Swarm ili k3s na nekoliko nodova, pa managed Kubernetes (EKS, GKE ili DigitalOcean Kubernetes) kada autoscaling, veliki broj servisa ili više timova opravdaju dodatnu složenost. O tome smo posebno pisali u članku o strategijama deploymenta na DigitalOceanu, AWS-u, Hetzneru i bare metal serverima.
Kubernetes kako treba
- Readiness i liveness probe (Kubernetes ignoriše
HEALTHCHECKiz Dockerfile-a), resource requests i limits, te pod disruption budgeti. - Helm chartovi ili Kustomize overlayi po okruženju, uz deployment preko GitOps pristupa sa Argo CD-om ili Fluxom.
- Horizontal Pod Autoscaler, ingress kontroler sa cert-managerom za TLS i mrežne politike između servisa.
- Centralizovani logovi, metrike u Prometheusu i Grafani te eksterne provjere dostupnosti – za manja okruženja osnovne potrebe pokriva već i self-hosted monitor dostupnosti.
Sigurnost i hardening kontejnera
Kontejneri izoluju procese, ali podrazumijevane postavke same po sebi nisu potpuna sigurnosna barijera. Zato je hardening dio svakog rješenja koje isporučujemo:
- Korisnik bez root privilegija u svakoj slici, te Docker rootless mode ili Podman na serverima gdje to ima smisla.
- Root fajl sistem samo za čitanje,
--cap-drop ALLuz samo one privilegije koje servisu zaista trebaju, ino-new-privileges. - Bez tajni u slikama i build argumentima: BuildKit secret mountovi tokom builda, Docker ili Kubernetes secrets (ili vault) tokom rada.
- Docker socket nikada ne montiramo u aplikacione kontejnere – to je praktično root pristup serveru.
- Privatni registryji (GitHub Container Registry, GitLab, AWS ECR ili self-hosted Harbor) sa kontrolom pristupa i pravilima čuvanja slika.
- Odvojene mreže, tako da je javno dostupan samo reverse proxy, a baze nikada ne izlažu portove internetu.
Kontejneri su odlični i kao jednokratni sandbox za razvoj – na istoj ideji počiva naš vodič o zaštiti razvojnog okruženja od zlonamjernih npm paketa.
Kontejnerizacija postojećih i legacy aplikacija
Većina Docker projekata ne kreće od nule. Kontejnerizujemo postojeće WordPress i WooCommerce sajtove, Laravel i klasične PHP aplikacije, Node.js API-je, Python scrapere i AI servise, obično bez izmjena koda osim konfiguracije.
- Konfiguracija prelazi u varijable okruženja, a stanje (uploadi, sesije, cache) izlazi iz kontejnera u volumene, object storage ili Redis.
- Stare verzije PHP-a ili Node.js-a rade jedna pored druge na istom serveru, svaka u svom kontejneru, dok se ne isplanira nadogradnja.
- Aplikacije pišu logove na stdout i stderr, pa Docker i vaš sistem za logove prikupljaju sve na jednom mjestu.
- Podatke migriramo prema uvježbanom planu prelaska, uz jasan put za povratak na staro stanje.
Uklapaju se i GPU opterećenja: uz NVIDIA Container Toolkit, serveri za lokalne AI modele rade u kontejnerima sa istom ponovljivošću kao ostatak sistema.
Najčešće greške u Docker kontejnerizaciji koje ispravljamo
- Korištenje
latesttaga u produkciji, pa novi build bez upozorenja povuče drugačiju baznu sliku. - Objavljivanje porta baze (
-p 5432:5432) na javnom serveru. Docker upisuje vlastita iptables pravila i zaobilazi UFW, pa je port otvoren cijelom svijetu. - Čuvanje podataka u sloju kontejnera u koji se piše, pa se gube kada se kontejner ponovo kreira.
- Jedna ogromna slika sa aplikacijom, cronom, bazom i Nginxom pod supervisordom, umjesto jednog procesa po kontejneru.
- Nema rotacije logova: podrazumijevani
json-filedriver može neprimjetno napuniti disk. - Kopiranje cijelog repozitorija prije instalacije zavisnosti, čime se cache poništava pri svakom commitu.
- Prosljeđivanje tajni kroz
ENViliARG, gdje ostaju vidljive u metapodacima slike.
Od čega zavisi cijena Docker kontejnerizacije
Obim posla se mnogo razlikuje od projekta do projekta, zato procjenu dajemo nakon kratke analize, a ne naslijepo. Glavni faktori cijene su ipak predvidivi:
- Broj servisa i komponenti sa stanjem: baze, redovi poruka, skladište fajlova, zakazani poslovi.
- Stanje postojećeg koda i količina konfiguracije koja je upisana direktno u kod.
- Broj okruženja (razvoj, staging, produkcija) i dubina CI/CD integracije.
- Ciljna orkestracija – Compose na jednom serveru je daleko manje posla od Kubernetes platforme.
- Sigurnosni i regulatorni zahtjevi, poput SBOM-a, potpisivanja slika ili audit logova.
- Jednokratna primopredaja ili kontinuirano održavanje slika i infrastrukture.
Kontejneri nisu uvijek pravi odgovor. Za jedan WordPress sajt dobro podešen server kojim upravljate preko open-source hosting panela može biti jednostavniji i jeftiniji – i ako je tako, reći ćemo vam to otvoreno.

Kako radimo
- Analiza: pregledamo aplikaciju, postojeće servere, proces deploymenta i bolne tačke, te popišemo svaki servis, zavisnost i mjesto gdje se čuvaju podaci.
- Plan: biramo bazne slike, ciljnu orkestraciju, registry, način upravljanja tajnama i CI/CD tok, pa sa vama usaglasimo obim posla.
- Izrada: pišemo multi-stage Dockerfile-ove, Compose fajlove ili Kubernetes manifeste, kao i pipeline koji gradi, skenira i objavljuje slike.
- Testiranje: provjeravamo da se sve ponaša kao u starom okruženju, radimo testove opterećenja i otkaza, te uvježbavamo rollback i vraćanje backupa.
- Puštanje u rad: prelazak radimo postepeno ili po blue-green principu, uz pojačan nadzor u prvim satima.
- Podrška: predajemo dokumentaciju i runbookove, a po želji i dalje ažuriramo bazne slike i nadziremo platformu.
Zašto CodeWiz
- Full-stack, a ne samo DevOps: Laravel, Node.js, WordPress i AI aplikacije i sami razvijamo, pa ih kontejnerizujemo uz razumijevanje kako se kod zaista ponaša.
- Open-source na prvom mjestu: Docker, Compose, k3s, Trivy, Traefik i Harbor vas oslobađaju zavisnosti od jednog dobavljača i troškova licenci.
- Rješenja po mjeri: ako je Compose na jednom serveru dovoljan, nećemo vam prodavati Kubernetes klaster.
- Fer cijene: vrhunski razvoj bez vrhunskih cijena, od tima iz Banje Luke koji radi na daljinu sa klijentima iz regiona i svijeta.
- Performanse i sigurnost na jednom mjestu: kontejneri, Cloudflare, Varnish i hardening servera su dio onoga što radimo svaki dan – saznajte više o CodeWizu.
Često postavljana pitanja
Koliko košta Docker kontejnerizacija?
Zavisi od broja servisa, stanja koda i ciljne orkestracije. Kontejnerizacija jedne web aplikacije sa bazom za Compose je mali projekat, dok je Kubernetes platforma sa više servisa i GitOps pristupom znatno veći posao. Jasnu procjenu dobijate nakon početne analize, prije nego što počne bilo kakav rad.
Koliko traje kontejnerizacija postojeće aplikacije?
Tipična web aplikacija sa bazom i cacheom često se može kontejnerizovati i pustiti u rad za nekoliko dana. Sistemi sa više servisa, migracijom podataka i orkestracijom na više servera obično traju nekoliko sedmica, najviše zbog testiranja i pažljivog prelaska.
Da li mi treba Kubernetes?
Na početku vjerovatno ne. Mnoge produkcijske aplikacije pouzdano rade na Docker Composeu ili Swarmu. Kubernetes se isplati kada imate mnogo servisa, trebate autoscaling ili više timova nezavisno objavljuje izmjene. Slike i konfiguraciju pravimo tako da kasniji prelazak na Kubernetes bude jednostavan.
Da li je Docker dovoljno siguran za produkciju?
Jeste, kada je pravilno podešen: korisnik bez root privilegija, minimalne bazne slike, oduzete privilegije, privatne mreže, tajne van slika i redovno skeniranje ranjivosti. Većina incidenata sa kontejnerima nastaje zbog loše konfiguracije, a ne zbog samog Dockera.
Da li će Docker usporiti moju aplikaciju?
Na Linuxu kontejneri direktno koriste kernel servera, pa je dodatno opterećenje procesora i memorije zanemarivo za uobičajene web aplikacije. Sporost koju ljudi primijete obično dolazi od dijeljenja fajlova u Docker Desktopu na macOS-u ili Windowsu tokom razvoja, a to rješavamo ciljanim bind mountovima i Compose Watchom.
Možete li kontejnerizovati WordPress ili staru PHP aplikaciju?
Možemo. Redovno kontejnerizujemo WordPress, WooCommerce, Laravel i stariji PHP kod, pri čemu uploadi i baze ostaju u trajnim volumenima, a starije verzije PHP-a rade izolovano dok ne budete spremni za nadogradnju.
Spremni za kontejnerizaciju vaše aplikacije?
Opišite nam svoj stack i gdje vas deployment danas najviše muči, a mi ćemo predložiti kontejnersko rješenje koje odgovara vašem timu i budžetu. Kontaktirajte nas da razgovaramo o projektu ili pogledajte cijelu ponudu naših usluga Docker kontejnerizacije.