Ograničenja memorije i CPU-a za kontejnere
Kako da postaviš gornju granicu memorije i CPU-a za kontejner, zašto bez toga jedna usluga obara sve ostale i kako da prepoznaš da je kernel ubio proces.
Ažurirano 23. avgust 2026.
Podrazumevano, kontejner može da uzme svu memoriju i sva jezgra na mašini. Na VDS-1 sa dva gigabajta to se završava predvidivo: jedan servis nabuja, kernel počne da ubija procese, a ono što padne nije on, nego baza pored njega.
Kako da postaviš gornju granicu
services:
app:
image: ghcr.io/example/app:1.5.0
deploy:
resources:
limits:
memory: 768M
cpus: "1.0"
reservations:
memory: 256M
Compose primenjuje deploy.resources.limits čak i uz običan docker compose up -d. Ekvivalent za docker run:
docker run -d --memory 768m --cpus 1.0 --memory-swap 768m <image>
Postavljanje --memory-swap na istu vrednost kao --memory zabranjuje svopovanje: iskren pad je bolji od mašine koja se jedva pomera satima.
Koliko dodeliti
Kreni od svog paketa i ostavi sistemu malo prostora.
| Paket | Memorija | Razumna ukupna granica za kontejnere |
|---|---|---|
| VDS-1 | 2 GB | do 1.5 GB |
| VDS-2 | 4 GB | do 3 GB |
| VDS-3 | 8 GB | do 6.5 GB |
| VDS-4 | 16 GB | do 14 GB |
| VDS-5 | 24 GB | do 21 GB |
| VDS-6 | 32 GB | do 29 GB |
Ostatak treba sistemu, kešu fajlova i samom Dockeru. Zbir limita veći od količine memorije nije greška u konfiguraciji — to je katastrofa koja samo čeka da se dogodi.
Za CPU: cpus: "1.0" je jedno puno jezgro. VDS-1 ima samo jedno jezgro, pa tu nema mnogo smisla ograničavati CPU, ali na VDS-4 i jačim vredi paziti da konfiguracija servera ne uzme svih šest.
Šta se zapravo troši
docker stats --no-stream
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
free -h
Posmatraj servis jedan dan pod opterećenjem i postavi limit na otprilike jedan i po puta veću vrednost od vrha. Previše stegnut limit je gori od nikakvog: servis će se restartovati baš kad ti je najpotrebniji.
htopibtoppreko celog ekrana rade samo u „Screen" konzoli (VNC). Tekstualna konzola ne prosleđuje veličinu prozora, tu je uvek 80×24, i interfejs se raspada. Za brza merenja u tekstualnoj konzoli koristidocker stats --no-streamifree -h.
Kako da prepoznaš da je ubijen zbog memorije
docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' <container>
sudo dmesg -T | grep -i -E "out of memory|killed process"
Izlazni kod 137 zajedno sa OOMKilled: true je nedvosmislena presuda. Odatle imaš dve opcije: podigni limit ako je bio previše nizak, ili otkrij zašto aplikacija stalno raste — curenje se ne leči dodavanjem memorije, samo se odlaže.
Java i drugi specijalni slučajevi
Java virtuelna mašina i dalje ponekad vidi memoriju hosta umesto limita kontejnera, pa dimenzioniše heap sa rezervom koje nema. Postavi je eksplicitno:
environment:
JAVA_TOOL_OPTIONS: "-Xmx512m -Xms256m"
Isto važi i za PostgreSQL (shared_buffers) i svaki servis sa sopstvenim pool-om.
Česte greške
- Nema postavljenih limita uopšte. Najčešći uzrok „mašina se zamrzla, ništa ne reaguje".
- Limit postoji, ali nema health check. Kontejner je ubijen i nikad se nije restartovao. Dodaj
restart: unless-stoppedihealthcheck— vidi ažuriranje kontejnera. - Zaboravio si na disk. Ograničio si memoriju, ali upisi udaraju u plafon: vidi brzina diska.