Docker sa VPS: Ano Talaga ang Nagbabago?
Pareho ang Docker engine, pero mas kapos ang VPS: nauubos ang RAM, nalalampasan ng published ports ang UFW, hindi bumabalik ang containers, at napupuno ang disk.
Mga pagbabago kapag nagpapatakbo ka ng Docker sa isang VPS
Ginagamit ng Docker sa isang VPS ang parehong engine at parehong images na ginagamit ng Docker sa iyong laptop, kaya gumagana pa rin ang lahat ng command na alam mo na. Ang nagbabago ay ang mga resource na nakapaligid dito. May ekstrang memory ang laptop, may firewall na walang nag-scan, at sapat ang laki ng disk kaya hindi mo ito kailangang bantayan. Ang inuupahang server ay may nakatakdang memory ceiling, public IP address na ini-scan ilang minuto matapos itong mag-boot, at root filesystem na pupunuin ng Docker nang hindi nagtatanong.
Apat na pagkakaiba ang sanhi ng karamihan sa mga problema sa maliit na server:
- Limitado ang memory, at tinutugunan ng kernel ang kakulangan sa pamamagitan ng pagpatay sa isang proseso.
- Direktang dumadaan sa UFW (uncomplicated firewall) ang isang published port dahil nagsusulat ang Docker ng sarili nitong firewall rules.
- Hindi awtomatikong bumabalik ang mga container matapos ang reboot maliban kung itinakda mo ito nang maaga.
- Patuloy na lumalaki ang images, containers, volumes, at build cache hanggang mapuno ang disk.
Tinatalakay sa bawat seksyon sa ibaba ang failure, ang string na aktuwal mong makikita, at ang gabay na nag-aayos dito nang detalyado. Kung hindi ka pa nakakasulat ng compose file, basahin muna ang Mga pangunahing kaalaman sa Docker Compose sa isang VPS at bumalik dito. Ipinapalagay ng page na ito na kaya mo nang mag-start ng stack.
Gaano karaming RAM ang ginagamit ng Docker container?
Mas kaunti kaysa sa inaasahan ng karamihan. Ang container ay isang process sa isang cgroup (control group), hindi isang virtual machine. Kaya walang guest kernel at walang fixed allocation. Ang ginagamit nitong resources ay nakadepende sa aktuwal na ina-access ng process sa loob. Dahil dito, kasya sa 2 GB ang isang buong stack kahit hindi magkakasya ang parehong stack kung virtual machines ang gamit.
Ang mga figure sa ibaba ay karaniwang idle value para sa stock images sa Ubuntu 24.04 na may default configuration. Kinuha ang mga ito mula sa docker stats ilang minuto matapos magsimula ang mga container. Panimulang batayan lamang ito para sa pagpaplano, hindi benchmark ng workload mo. Patakbuhin ang docker stats --no-stream sa sarili mong server bago ka umasa sa anumang figure, kasama na ang mga ito.
The data behind this chart
[
{
"label": "nginx",
"idle_mb": 8,
"budget_mb": 64
},
{
"label": "Redis 7",
"idle_mb": 12,
"budget_mb": 128
},
{
"label": "Traefik v3",
"idle_mb": 40,
"budget_mb": 128
},
{
"label": "PostgreSQL 16",
"idle_mb": 45,
"budget_mb": 512
},
{
"label": "Uptime Kuma",
"idle_mb": 95,
"budget_mb": 256
},
{
"label": "MariaDB 11",
"idle_mb": 190,
"budget_mb": 512
},
{
"label": "Nextcloud (Apache)",
"idle_mb": 210,
"budget_mb": 768
}
]Magkaiba ang gamit ng dalawang column. Ang idle_mb ang ginagamit ng container kapag wala itong ginagawa. Ang budget_mb ang dapat ireserba kapag nagpaplano, dahil hindi idle ang aktuwal na paggamit. Karaniwang nasa 45 MB ang idle usage ng PostgreSQL at nangangailangan ito ng 512 MB kapag aktibo na ang mga connection, sort, at cache. Gamitin ang budget column sa pagpaplano. Gamitin ang idle column sa pag-debug.
Pansinin ang pattern sa 7 row na iyon. Nasa 8 MB ang idle usage ng nginx at nasa 210 MB naman ang Nextcloud. Halos walang dagdag na memory ang proxy sa harap ng mga application mo. Ang database at PHP application ang dapat pagbatayan sa pag-size ng server.
May isang babala tungkol sa docker stats: kasama sa memory figure ang page cache na na-load dahil sa mga file read ng container. Kaya maaari itong patuloy na tumaas ilang sandali matapos magsimula, bago maging stable. I-monitor ito nang isang oras bago magpasya na may memory leak.
Pagpili ng laki ng VPS: ano ang kasya sa 2 GB, 4 GB, at 8 GB
Ibawas muna ang bahagi ng host bago ang lahat. Ang kernel, systemd, journald, sshd, at Docker daemon ay gumagamit ng parehong RAM na ginagamit ng iyong mga container, at ang dockerd kasama ng containerd ay kumokonsumo ng humigit-kumulang 100 MB nito. Kailangan mo rin ng libreng memory para sa page cache at para sa biglaang pagtaas ng gamit kapag tumatakbo ang image build o database dump.
The data behind this chart
[
{
"plan": "2 GB VPS",
"total_mb": 2048,
"host_reserve_mb": 768,
"container_mb": 1280
},
{
"plan": "4 GB VPS",
"total_mb": 4096,
"host_reserve_mb": 1024,
"container_mb": 3072
},
{
"plan": "8 GB VPS",
"total_mb": 8192,
"host_reserve_mb": 1536,
"container_mb": 6656
}
]Saklaw ng host_reserve_mb ang operating system, Docker daemon, at headroom na nagpapanatiling responsive sa server kapag may load. Ang natitira ay container_mb, at iyon lamang ang halagang maaari mong ilaan. Lumalaki ang reserve ayon sa plan, mula 768 MB sa pinakamaliit na server hanggang 1536 MB sa pinakamalaki, dahil mas maraming container ang pinapatakbo ng mas malaking server, mas maraming log ang sinusulat, at mas malaking page cache ang kailangan.
Nag-iiwan ang 2 GB plan ng 1280 MB para sa mga container. Gamitin ang 512 MB nito para sa PostgreSQL at 128 MB para sa Traefik, at kalahati nito ay nagamit na agad. Ang natitira ay sapat para sa dalawang maliit na application na humigit-kumulang 256 MB bawat isa. Totoo at kapaki-pakinabang na server ito. Hindi ito sapat para sa Nextcloud at isang search cluster.
Nag-iiwan ang 4 GB plan ng 3072 MB, na sapat para sa database, reverse proxy, tatlong application, at isang monitoring container na sabay-sabay na tumatakbo. Ito ang pinakamaliit na laki na sulit gamitin para sa anumang mahalagang workload, dahil ang ekstrang memory ang sumasalo sa epekto ng isang problemadong deploy.
Nag-iiwan ang 8 GB plan ng 6656 MB mula sa kabuuang 8192 MB, at karaniwang lumilipat ang limitasyon mula sa memory papunta sa CPU o disk throughput. May isang uri ng container na nagtatakda ng laki batay sa configuration nito at hindi sa load: nagrereserba ang local model server ng KV cache na proporsyonal sa context window nito, kaya maaaring magdagdag ng gigabytes sa budget ang pagtaas ng num_ctx ng Ollama bago pa dumating ang isang request. Kung ipinapakita ng kalkulasyon na hindi kasya ang iyong stack, bumili ng mas malaking plan sa halip na piliting magkasya ito sa pamamagitan ng tuning: ipinapaliwanag ng aktuwal na halaga ng VPS kung magkano bawat buwan ang kapalit ng dagdag na gigabytes.
Dalawang tuntunin ang nagpapanatiling tama sa kalkulasyon. Magtakda ng memory limit para sa bawat service upang hindi makuha ng isang runaway process ang buong server. At huwag ubusin ang buong budget, dahil parehong nangangailangan ng memory ang docker compose build at pg_dump sa pinakamasamang pagkakataon. Nasa Memory limits sa Docker Compose ang syntax at mga karaniwang problema.
Bakit lumalabas ang container ko na may exit code 137?
Pinatay ito ng kernel. Ang 137 ay 128 dagdag ang 9, at ang signal 9 ay SIGKILL. Humingi ang container ng mas maraming memory kaysa sa pinapayagan dito, kaya winakasan ito ng out of memory (OOM) killer.
CONTAINER ID IMAGE STATUS
9f2c1a4d7b3e postgres:16 Exited (137) 4 minutes agoKumpirmahin ang sanhi sa halip na manghula:
docker inspect my-db | grep -i oomkilled
sudo journalctl -k | grep -i "out of memory"Ibig sabihin ng "OOMKilled": true, naabot ng container ang sarili nitong cgroup limit, at tinutukoy ng kernel log ang prosesong pinili nito:
Memory cgroup out of memory: Killed process 2417 (postgres) total-vm:1284416kBIto ang mabuting sitwasyon dahil isang container lamang ang naapektuhan. Ang masamang sitwasyon ay container na walang limit. Kapag walang limit, ang buong machine ang ceiling nito. Dahil dito, maaaring ubusin ng memory leak sa isang serbisyo ang resources ng host, at pipili ang kernel ng prosesong papatayin batay sa laki nito sa buong system. Mawawala sa log line ang prefix na Memory cgroup at magiging Out of memory: Killed process 2417 (postgres). Madalas na database ang napipili nitong proseso, habang patuloy na tumatakbo ang container na nagkaroon ng leak. Kaya mas mahalaga ang pagkakaroon ng limit sa bawat serbisyo kaysa sa eksaktong value ng alinmang limit.
Binabago ng swap ang timing, hindi ang arithmetic. Karamihan sa VPS images ay walang swap. Suriin ito gamit ang swapon --show. Wala itong ipi-print kapag walang swap. Nagbibigay ang swap file ng lugar kung saan maaaring ilipat ng kernel ang cold pages. Nagbibigay ito ng ilang minuto para mapansin ang problema.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -hDapat nang magpakita ang free -h ng non-zero na total sa Swap row. Hindi nagdaragdag ng RAM ang swap. Kapag palaging kapos sa memory ang isang box, bumabagal ito nang husto at maaaring hindi ka na makapag-SSH para ayusin ito. Ituring ang swap bilang alarm buffer at ayusin ang resource sizing.
Bakit hindi bina-block ng UFW ang published Docker port?
Dahil hindi dumadaan ang traffic sa chain na binabantayan ng UFW. Kapag nag-publish ka ng port gamit ang -p 5432:5432 o isang compose ports: entry, nagsusulat ang daemon ng DNAT (destination network address translation) rule sa nat table at accept rule sa sarili nitong DOCKER chain. Ipinapasa ang packet na nakalaan sa container sa container sa halip na ihatid sa host, kaya dumadaan ito sa FORWARD path at hindi sa INPUT rules na isinusulat ng UFW.
Makikita mo ito sa server:
sudo ufw status | grep 5432
sudo iptables -t nat -L DOCKER -n | grep 5432Maaaring mag-print ang UFW ng 5432 DENY IN Anywhere habang may hawak na DNAT tcp ... to:172.18.0.2:5432 rule ang nat table para sa parehong port. Mula sa ibang machine, kumokonekta pa rin ang nc -vz your.server.ip 5432. Nasa public internet ang database, pero sinasabi ng firewall na hindi ito nakalantad.
Ang solusyon ay mag-publish ng mas kaunti. Ang mga container sa iisang compose project ay nagbabahagi ng network at naaabot ang isa’t isa gamit ang service name, kaya hindi kailangan ng database na nagsisilbi lamang sa katabing application ang anumang ports: entry. Kung kailangan mo ng local access, i-bind ang publish sa loopback:
services:
db:
image: postgres:16
ports:
- "127.0.0.1:5432:5432"Pagkatapos ng docker compose up -d, mabibigo ang nc -vz your.server.ip 5432 mula sa labas, habang gagana pa rin ang psql -h 127.0.0.1 -p 5432 sa mismong box. Sa maayos na maliit na stack, ang reverse proxy lamang ang nagpa-publish ng kahit ano, sa ports 80 at 443. Tinalakay sa Bakit nilalampasan ng Docker published ports ang UFW ang DOCKER-USER chain para sa mga sitwasyong kailangan mong mag-publish ng port at i-filter pa rin ito, at sa Mga batayan ng UFW firewall ang mga host rule sa ilalim nito.
Bakit nawawala ang mga container ko pagkatapos ng reboot?
Dahil walang nagsabi sa mga ito na bumalik. Nilikha ang isang container na may restart policy na no kapag wala kang itinakda, kaya kapag nag-reboot, mananatili itong stopped at hindi ito aasikasuhin ng daemon. Hindi bihira ang mga reboot sa isang VPS: maaaring magmula ang mga ito sa kernel updates ng unattended upgrades, maintenance ng provider, at sa OOM sequence sa itaas.
Dalawang bagay ang dapat matupad. Dapat magsimula ang daemon sa boot:
systemctl is-enabled dockerIpinapakita nito ang enabled sa isang karaniwang Ubuntu install. Pagkatapos, kailangan ng bawat service ng policy:
services:
app:
image: ghcr.io/example/app:1.4
restart: unless-stoppedIbinabalik ng unless-stopped ang container pagkatapos ng reboot at iginagalang nito ang container na sinadya mong ihinto. Nire-restart din ng always ang mga container na sinadya mong ihinto sa tuwing nagre-restart ang daemon. Maaari itong maging sorpresa habang nagde-debug. Hindi sapat na i-edit lamang ang file, dahil itinatakda ang restart policy kapag nililikha ang container. Patakbuhin ang docker compose up -d upang muli itong malikha, pagkatapos ay suriin ang aktuwal na value:
docker inspect my-app | grep -A3 RestartPolicyPagkatapos, sadyang i-reboot ang box at patakbuhin ang docker compose ps sa project directory. Kung nakaligtas ang stack sa planadong reboot, makaliligtas din ito sa hindi planado. Kung kailangan ng iyong stack ng ordering guarantee o one-shot job sa boot, mas angkop ang systemd unit: nasa pagsisimula ng Docker Compose sa boot ang unit file. Para malaman kung talagang nagse-serve ang container na bumalik, magdagdag ng Compose healthchecks.
Bakit puno ang disk ng VPS ko?
Dahil pinananatili ng Docker ang lahat hangga't hindi mo ito inuutusang maglinis. Kasama rito ang bawat image tag na na-pull mo, bawat tumigil na container, bawat anonymous volume na naiwan matapos ang recreate, at bawat layer ng build cache. Sa root filesystem na 40 GB o 80 GB, na karaniwan sa ganitong laki ng plan, nauuwi ito sa outage sa loob ng ilang buwan sa halip na ilang taon.
Hindi agad mukhang crash ang punô na disk. Makakatanggap ka ng no space left on device mula sa isang container, mula sa apt, mula sa journald, at mula sa docker pull sa loob ng parehong oras. Hihinto ang PostgreSQL sa pagtanggap ng writes. Nananatiling gumagana ang server, kaya mas mahirap itong mapansin kaysa sa reboot loop.
Suriin muna bago mag-delete:
docker system df
df -h /Hinahati ng docker system df ang kabuuang paggamit sa images, containers, local volumes, at build cache, at may katabing RECLAIMABLE column para sa bawat isa. Sa server na gumagawa ng sarili nitong images, karaniwang pinakamalaki ang build cache.
docker image prune -a
docker builder prune
docker system dfInaalis ng docker image prune -a ang bawat image na hindi ginagamit ng anumang container. Nililinis ng docker builder prune ang build cache. Ligtas ang dalawang ito habang tumatakbo ang mga serbisyo dahil nilalaktawan ang anumang ginagamit. Hindi ligtas ang docker system prune --volumes, na nagde-delete ng bawat volume na walang container na kasalukuyang tumutukoy rito. Ganito mismo ang kalagayan ng stack na itinigil mo para sa weekend, at kasama nitong made-delete ang database volume nito. Basahin ang bind mounts kumpara sa named volumes bago mong gamitin ang flag na iyon, at mag-backup muna.
Mas tahimik na lumalaki ang container logs. Walang size limit ang default na json-file driver, kaya maaaring magsulat ang isang container na maraming log sa gigabytes ng data sa /var/lib/docker/containers. Magtakda ng limit para sa bawat container sa /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}Ilapat ito gamit ang sudo systemctl restart docker, na nagre-restart sa iyong mga container, kaya piliin ang tamang oras. Nalalapat ang limit sa mga container na gagawin pagkatapos ng pagbabago, kaya i-recreate ang kasalukuyang tumatakbo gamit ang docker compose up -d --force-recreate at kumpirmahin:
docker inspect my-app | grep -A5 LogConfig
sudo du -sh /var/lib/docker/containersDapat ipakita ng inspect output na naka-set ang max-size. Kung walang laman ito, nauna nang ginawa ang container bago ang pagbabago at patuloy pa rin itong nagsusulat nang walang limit.
Mga gawi para manatiling maayos ang isang maliit na Docker box
Wala sa mga ito ang nangangailangan ng dashboard o tool na kailangan mo pang pag-aralan.
- Patakbuhin ang
docker system dfatdf -h /sa unang araw ng bawat buwan. Dalawang command, tatlumpung segundo, at makikita mo ang trend bago pa ito mauwi sa outage. - Magtakda ng memory limit para sa bawat service, pati sa mga service na tiwala kang maliit lang. Ginagawang isang container na kailangang i-restart ng limit ang outage na makaaapekto sana sa buong host.
- I-monitor ang box mula sa ibang lokasyon para malaman mo ang memory o disk pressure bago kumilos ang kernel. Tumatakbo ang Uptime Kuma sa isang container at nasa humigit-kumulang 95 MB ang idle memory nito.
- I-back up ang volumes, hindi ang containers. Maaaring itapon ang container, pero hindi ang volume. Saklaw ng restic backups sa isang VPS ang schedule at restore test.
- I-pin ang image tags sa compose file at i-update ang mga ito sa araw na pinili mo. Sa
latest, ang version na makukuha mo mula sa susunod nadocker compose pullay ang bersyong ni-release nang umagang iyon.
Mananatiling maayos sa loob ng maraming taon ang isang maliit na VPS na nagpapatakbo ng Docker kapag nasa tamang saklaw ang apat na numero: memory budget, listahan ng published ports, restart policy ng bawat service, at free disk. Ang lahat ng iba pa ay kapareho ng Docker na ginagamit mo na sa bahay.
FAQ
Gaano karaming RAM ang kailangan ko para magpatakbo ng Docker sa isang VPS?
Mababa ang resource requirement ng Docker mismo. Karaniwang nasa 100 MB ang pinagsamang gamit ng daemon at containerd, at ang mga container ang bumubuo sa natitirang requirement. Ilaan muna ang bahagi para sa host: 768 MB sa isang 2048 MB na server para sa operating system, daemon, at headroom. Dahil dito, 1280 MB ang matitira para sa mga container. Kasya rito ang database na gumagamit ng 512 MB, reverse proxy na gumagamit ng 128 MB, at dalawang maliit na application. Sukatin ang sarili mong stack gamit ang docker stats --no-stream sa halip na umasa sa anumang inilathalang figure.
Maaari ba akong magpatakbo ng Docker sa isang 1 GB VPS?
Oo, para sa isa o dalawang magagaang container. Magdagdag muna ng swap file bago magsimula. Humigit-kumulang kalahati ng 1 GB server ang nagagamit kapag tumatakbo na ang operating system at Docker daemon. Sapat ang natitirang memory para sa isang maliit na application at reverse proxy, ngunit hindi para sa database na nasa aktuwal na load. Maaaring mabigo ang pagbuo ng images sa ganitong kaliit na server o mapatigil ang ibang proseso. Bumuo ng image sa ibang server at i-pull ang natapos na image.
Pinoprotektahan ba ng UFW ang isang Docker container?
Hindi para sa mga port na ipinublish mo. Gumagawa ang Docker ng sarili nitong DNAT at forward rules. Dahil dito, ang packet na nakalaan sa isang published container port ay ipinapasa sa container sa halip na ihatid sa host. Hindi ito nakikita ng INPUT rules na pinamamahalaan ng UFW. Maaaring aktibo ang ufw deny 5432 habang tumatanggap ng koneksyon mula sa internet ang port na iyon. I-publish ito sa loopback gamit ang 127.0.0.1:5432:5432, huwag i-publish ang mga internal service, o mag-filter sa DOCKER-USER chain.
Awtomatiko bang magre-restart ang mga container ko pagkatapos mag-reboot ng VPS?
Kung ginawa lamang ang mga ito na may restart policy. Itakda ang restart: unless-stopped sa bawat service, patakbuhin ang docker compose up -d upang muling malikha ang mga container na may policy na iyon, at tiyaking ipinapakita ng systemctl is-enabled docker ang enabled. Pagkatapos, magsagawa ng reboot at suriin ang docker compose ps. Ang restart policy na hindi mo pa nasusubukan ay hindi maaasahang restart policy.
Gaano kadalas dapat mag-prune ng Docker images?
Sapat na ang isang beses bawat buwan para sa karamihan ng maliliit na server, o kapag nag-ulat ang docker system df ng reclaimable space na kailangan mo. Ligtas gamitin ang docker image prune -a at docker builder prune habang tumatakbo ang mga service, dahil nilalaktawan ang mga image at cache na ginagamit. Iwasan ang docker system prune --volumes maliban kung alam mo kung aling mga volume ang walang reference, dahil binubura nito ang data ng anumang stack na pansamantalang naka-stop.