SSD Nodes Learn 🎉 VPS kutoka $5.50/mwezi
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-08-13

Jinsi Docker inavyofanya kazi kwenye VPS

Kujua tofauti za Docker kwenye VPS ni muhimu. Makala hii inaelezea jinsi ya kuzuia hitilafu za RAM, jinsi ya kusanidi UFW kwa usahihi, na kudhibiti diski inayojaza faili.

Mabadiliko yanayotokea unapoendesha Docker kwenye VPS

Docker kwenye VPS huendesha injini ileile na images zilezile kama Docker kwenye laptop yako, kwa hivyo kila amri unayoijua bado inafanya kazi. Kinachobadilika ni mazingira yanayoizunguka. Laptop ina kumbukumbu ya ziada, firewall ambayo hakuna anayeichunguza, na diski kubwa kiasi kwamba huna haja ya kuiangalia. Seva iliyokodishwa ina kikomo cha kumbukumbu, anwani ya IP ya umma inayochunguzwa ndani ya dakika chache baada ya kuwaka, na mfumo wa faili wa root ambao Docker itaujaza bila kuuliza.

Tofauti nne husababisha matatizo mengi kwenye seva ndogo:

  • Kumbukumbu ina kikomo, na kernel hutatua uhaba kwa kuua mchakato (process).
  • Port iliyochapishwa (published port) hupita moja kwa moja kwenye UFW (uncomplicated firewall), kwa sababu Docker huandika sheria zake za firewall.
  • Containers hazirudi baada ya reboot isipokuwa kama uliomba hivyo mapema.
  • Images, containers, volumes na build cache hukua hadi diski ijae.

Kila sehemu hapa chini inataja hitilafu, ujumbe utakaouona, na mwongozo unaotatua tatizo hilo kwa kina. Ikiwa bado hujaandika faili ya compose, soma Misingi ya Docker Compose kwenye VPS kwanza kisha urudi. Ukurasa huu unadhani kuwa tayari unaweza kuwasha stack.

Docker container hutumia kiasi gani cha RAM?

Kidogo kuliko wengi wanavyodhani. Container ni mchakato ndani ya cgroup (control group), si mashine ya mtandaoni (virtual machine), kwa hivyo hakuna kernel ya mgeni wala mgao uliowekwa. Gharama ni kile ambacho mchakato wa ndani unagusa. Hii ndiyo sababu stack kamili inatosha katika 2 GB wakati stack hiyo hiyo ikijengwa kwa mashine za mtandaoni isingetosha.

Takwimu hapa chini ni namba za kawaida za hali ya kutofanya kazi (idle) kwa images za kawaida kwenye Ubuntu 24.04 na usanidi chaguo-msingi, zilizosomwa kutoka docker stats dakika chache baada ya kuanza. Hizi ni sehemu ya kuanzia kwa ajili ya kupanga, si kipimo cha kazi yako (benchmark). Endesha docker stats --no-stream kwenye seva yako mwenyewe kabla ya kuamini takwimu yoyote, ikiwemo hizi.

ChartTypical idle container memory, stock images, megabytes
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
  }
]

Safu wima mbili hufanya kazi tofauti. idle_mb ni kile ambacho container hutumia wakati haifanyi kazi yoyote. budget_mb ni kile cha kutenga unapopanga, kwa sababu matumizi halisi si ya kutofanya kazi. PostgreSQL hutulia karibu na 45 MB na huhitaji 512 MB pindi miunganisho, upangaji (sorts) na cache zinapokuwa hai. Panga kwa kutumia safu ya bajeti. Fanya utatuzi (debug) kwa kutumia safu ya idle.

Angalia umbo la zile 7 safu. nginx hutulia katika 8 MB na Nextcloud katika 210 MB. Proxy iliyo mbele ya programu zako haina gharama kubwa. Database na programu ya PHP ndizo unazopaswa kuzingatia wakati wa kupima ukubwa wa seva yako.

Onyo moja kuhusu docker stats: takwimu ya kumbukumbu inajumuisha page cache ambayo usomaji wa faili wa container yenyewe umevuta, kwa hivyo hupanda kwa muda baada ya kuanza na kisha hutulia. Iangalie kwa saa moja kabla ya kuamua kuwa kuna kitu kinavuja (leaking).

Kukadiria VPS: nini kinafaa kwenye 2 GB, 4 GB na 8 GB

Ondoa kwanza sehemu inayotumiwa na mwenyeji (host). Kernel, systemd, journald, sshd na Docker daemon zote hukaa kwenye RAM sawa na containers zako, na dockerd pamoja na containerd hutumia takriban 100 MB ya RAM hiyo. Unahitaji pia kumbukumbu ya ziada kwa ajili ya page cache, na kwa ajili ya ongezeko la matumizi wakati wa kujenga image au kufanya database dump.

ChartRAM budget by plan size, megabytes
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
  }
]

host_reserve_mb inashughulikia mfumo wa uendeshaji, Docker daemon na nafasi ya ziada inayofanya seva iwe na mwitikio mzuri chini ya mzigo. Kilichobaki ni container_mb, na hiyo ndiyo namba pekee unayoweza kutumia. Akiba hii huongezeka kulingana na mpango, kuanzia 768 MB kwenye seva ndogo zaidi hadi 1536 MB kwenye seva kubwa zaidi, kwa sababu seva kubwa huendesha containers nyingi zaidi, huandika log nyingi zaidi na huhitaji page cache kubwa zaidi.

Mpango wa 2 GB huacha 1280 MB kwa ajili ya containers. Tumia 512 MB ya hiyo kwa PostgreSQL na 128 MB kwa Traefik, na nusu yake itakuwa imekwisha. Kilichobaki ni kwa ajili ya programu mbili ndogo za takriban 256 MB kila moja. Hiyo ni seva halisi na yenye manufaa. Haina nafasi ya Nextcloud na search cluster juu yake.

Mpango wa 4 GB huacha 3072 MB, ambapo database, reverse proxy, programu tatu na container ya ufuatiliaji (monitoring) vyote vinafaa kwa wakati mmoja. Hii ndiyo saizi ndogo zaidi inayofaa kwa kitu chochote unachokijali, kwa sababu kumbukumbu ya ziada ndiyo inayosaidia kuhimili deploy mbaya.

Mpango wa 8 GB huacha 6656 MB kati ya 8192 MB zake, na kikomo kwa kawaida huhama kutoka kumbukumbu kwenda CPU au kasi ya disk (throughput). Ikiwa hesabu inaonyesha kuwa stack yako haitoshi, nunua mpango mkubwa zaidi badala ya kujaribu kuibadilisha: gharama halisi ya VPS inaelezea thamani ya gigabytes za ziada kwa mwezi.

Sheria mbili huweka hesabu hii kuwa sahihi. Weka kikomo cha kumbukumbu (memory limit) kwenye kila huduma, ili mchakato mmoja usiodhibitiwa usimalize rasilimali za seva nzima. Na uache sehemu ya juu ya bajeti bila kutumika, kwa sababu docker compose build na pg_dump zote huhitaji kumbukumbu wakati mbaya zaidi. Memory limits in Docker Compose ina syntax na mitego ya kuepuka.

Kwa nini container yangu inazima na kutoa code 137?

Hii hutokea kwa sababu kernel imeifunga. 137 ni 128 jumlisha 9, na signal 9 ni SIGKILL. Container iliomba kumbukumbu (memory) zaidi ya ile iliyoruhusiwa, na mchakato wa out of memory (OOM) killer ukaifunga.

CONTAINER ID   IMAGE         STATUS
9f2c1a4d7b3e   postgres:16   Exited (137) 4 minutes ago

Thibitisha sababu badala ya kukisia:

docker inspect my-db | grep -i oomkilled
sudo journalctl -k | grep -i "out of memory"

"OOMKilled": true inamaanisha container imefikia kikomo chake cha cgroup, na log ya kernel inataja mchakato (process) iliyouchagua:

Memory cgroup out of memory: Killed process 2417 (postgres) total-vm:1284416kB

Hali hii ni bora, kwa sababu uharibifu umeishia kwenye container moja tu. Hali mbaya ni pale container inapokuwa haina kikomo chochote. Bila kikomo, uwezo wake wa juu ni mashine nzima, hivyo leak katika huduma moja huinyima host rasilimali, na kernel huchagua mhanga kulingana na ukubwa katika mfumo mzima. Mstari wa log hupoteza prefix ya Memory cgroup na kusomeka Out of memory: Killed process 2417 (postgres). Mchakato unaochaguliwa mara nyingi ni database yako, wakati container iliyosababisha leak inaendelea kufanya kazi. Hii ndiyo sababu kuweka kikomo kwa kila huduma ni muhimu zaidi kuliko thamani kamili ya kikomo kimoja.

Swap hubadilisha muda wa kutokea kwa tatizo, si hesabu ya kumbukumbu. Picha nyingi za VPS huja bila swap. Angalia kwa kutumia swapon --show, ambayo haitoi matokeo yoyote ikiwa swap haipo. Faili ya swap huipa kernel mahali pa kuweka kurasa (pages) zisizotumika, jambo linalokupa dakika chache za kugundua tatizo.

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 -h

free -h sasa inapaswa kuonyesha jumla isiyo sifuri katika mstari wa Swap. Swap haiongezi RAM. Mashine iliyo chini ya shinikizo la kumbukumbu mara kwa mara huwa polepole kiasi kwamba huwezi kuingia kupitia SSH ili kurekebisha, kwa hivyo chukulia swap kama buffer ya tahadhari na urekebishe ukubwa wake.

Kwa nini UFW haizuii port yangu ya Docker iliyochapishwa?

Kwa sababu trafiki haifiki kamwe kwenye chain inayolindwa na UFW. Unapochapisha port kwa kutumia -p 5432:5432 au ingizo la ports: kwenye compose, daemon huandika sheria ya DNAT (destination network address translation) kwenye jedwali la nat na sheria ya kukubali (accept) kwenye chain yake ya DOCKER. Pakiti inayoelekezwa kwenye container husukumwa (forwarded) kwenye container hiyo badala ya kupelekwa kwa host, kwa hivyo inashughulikiwa kwenye njia ya FORWARD na haipiti kamwe sheria za INPUT zilizoandikwa na UFW.

Unaweza kuona hili likitokea kwenye seva:

sudo ufw status | grep 5432
sudo iptables -t nat -L DOCKER -n | grep 5432

UFW inaweza kuonyesha 5432 DENY IN Anywhere wakati jedwali la nat linashikilia sheria ya DNAT tcp ... to:172.18.0.2:5432 kwa port hiyo hiyo. Kutoka kwa mashine nyingine, nc -vz your.server.ip 5432 bado inaunganisha. Database iko kwenye mtandao wa umma na firewall inasema haipo.

Suluhisho ni kuchapisha kidogo. Container katika mradi mmoja wa compose hushiriki mtandao na kufikiana kwa kutumia jina la huduma, kwa hivyo database inayohudumia programu iliyo karibu nayo haihitaji ingizo la ports: hata kidogo. Unapotaka ufikiaji wa ndani, funga (bind) uchapishaji kwenye loopback:

services:
  db:
    image: postgres:16
    ports:
      - "127.0.0.1:5432:5432"

Baada ya docker compose up -d, nc -vz your.server.ip 5432 kutoka nje inashindwa, na psql -h 127.0.0.1 -p 5432 kwenye mashine hiyo bado inafanya kazi. Katika stack ndogo yenye afya, reverse proxy pekee ndiyo inayochapisha chochote, kwenye 80 na 443. Kwa nini ports zilizochapishwa na Docker hupita UFW inashughulikia chain ya DOCKER-USER kwa hali ambazo lazima uchapishe port na bado uichuje, na Misingi ya firewall ya UFW inashughulikia sheria za host zilizo chini yake.

Kwa nini container zangu zimepotea baada ya reboot?

Kwa sababu hakuna amri iliyowaambia warudi. Container huundwa ikiwa na sera ya restart ya no isipokuwa ukiweka nyingine, kwa hivyo reboot huiacha ikiwa imesimama na daemon haijali. Reboot si jambo adimu kwenye VPS: kernel updates kutoka kwa unattended upgrades, matengenezo ya mtoa huduma, na mlolongo wa OOM hapo juu yote husababisha reboot.

Mambo mawili lazima yawe kweli. Daemon lazima ianze wakati wa boot:

systemctl is-enabled docker

Hiyo huchapisha enabled kwenye usakinishaji wa kawaida wa Ubuntu. Kisha kila huduma inahitaji sera:

services:
  app:
    image: ghcr.io/example/app:1.4
    restart: unless-stopped

unless-stopped huirudisha container baada ya reboot na huheshimu container uliyoisimamisha kwa makusudi. always pia huanzisha upya zile ulizozisimamisha kwa makusudi wakati wowote daemon inapoanzishwa upya, jambo ambalo ni mshangao katikati ya utatuzi wa hitilafu. Kuhariri faili pekee hakutoshi, kwa sababu sera ya restart huwekwa wakati container inaundwa. Tekeleza docker compose up -d ili iundwe upya, kisha angalia thamani ya sasa:

docker inspect my-app | grep -A3 RestartPolicy

Kisha fanya reboot ya seva kwa makusudi na utekeleze docker compose ps kwenye saraka ya mradi. Stack inayoweza kuhimili reboot iliyopangwa inaweza kuhimili ile isiyopangwa. Ikiwa stack yako inahitaji mpangilio maalum au kazi ya mara moja wakati wa boot, unit ya systemd ndiyo zana bora zaidi: kuanzisha Docker Compose wakati wa boot ina faili ya unit. Ili kujua kama container iliyorejea inafanya kazi kweli, ongeza Compose healthchecks.

Kwa nini diski ya VPS yangu imejaa?

Kwa sababu Docker huhifadhi kila kitu hadi utakapoiagiza isifanye hivyo. Kila image tag uliyowahi kudownload, kila container iliyosimamishwa, kila anonymous volume iliyoachwa baada ya recreate, na kila layer ya build cache hubaki kwenye diski. Kwenye root filesystem ya 40 GB au 80 GB, ambayo ni kawaida kwa ukubwa wa mipango hii, hiyo husababisha kukatika kwa huduma ndani ya miezi michache badala ya miaka.

Diski iliyojaa haionekani kama crash. Utapata no space left on device kutoka kwa container, kutoka kwa apt, kutoka kwa journald na kutoka kwa docker pull ndani ya saa moja. PostgreSQL huacha kukubali uandikaji. Seva bado inafanya kazi, jambo linalofanya iwe vigumu kugundua kuliko reboot loop.

Kagua kabla ya kufuta:

docker system df
df -h /

docker system df hugawanya jumla ya nafasi katika images, containers, local volumes na build cache, ikiwa na safu ya RECLAIMABLE kando ya kila moja. Kwenye seva inayojijengea images zake, build cache kwa kawaida ndiyo sehemu kubwa zaidi.

docker image prune -a
docker builder prune
docker system df

docker image prune -a huondoa kila image ambayo haina container inayotumia. docker builder prune husafisha build cache. Zote ni salama wakati huduma zinafanya kazi, kwa sababu chochote kinachotumika hukiukwa. Kitu ambacho si salama ni docker system prune --volumes, ambacho hufuta kila volume ambayo haina container inayoiunganisha kwa sasa. Stack uliyoisimamisha kwa ajili ya wikendi ina hali hiyo, na database volume yake itafutwa pia. Soma bind mounts dhidi ya named volumes kabla ya kuandika flag hiyo, na chukua backup kwanza.

Log za container ni ukuaji wa kimya kimya. Dereva chaguo-msingi wa json-file hana kikomo cha ukubwa, kwa hivyo container inayozalisha log nyingi huandika gigabytes kwenye /var/lib/docker/containers. Weka kikomo kwa kila container kwenye /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Tekeleza kwa sudo systemctl restart docker, ambayo huanzisha upya containers zako, kwa hivyo chagua wakati mwafaka. Kikomo hicho hutumika kwa containers zilizoundwa baada ya mabadiliko hayo, kwa hivyo recreate zile zinazofanya kazi kwa docker compose up -d --force-recreate na uthibitishe:

docker inspect my-app | grep -A5 LogConfig
sudo du -sh /var/lib/docker/containers

Matokeo ya inspect yanapaswa kuonyesha max-size imewekwa. Ikiwa ni tupu, container hiyo ilikuwepo kabla ya mabadiliko na bado inaandika bila kikomo.

Tabia zinazodumisha afya ya seva ndogo ya Docker

Hakuna kati ya haya yanayohitaji dashboard au zana unayopaswa kujifunza.

  • Tekeleza docker system df na df -h / kila tarehe moja ya mwezi. Amri mbili, sekunde thelathini, na utaona mwelekeo wa matumizi muda mrefu kabla ya tatizo kuwa kubwa.
  • Weka kikomo cha kumbukumbu (memory limit) kwa kila huduma, hata zile unazohakikisha ni ndogo. Kikomo hiki hubadilisha tatizo la seva nzima kuwa container moja tu inayowashwa upya.
  • Fuatilia seva kutoka sehemu nyingine, ili upate taarifa kuhusu shinikizo la kumbukumbu au diski kabla kernel haijachukua hatua. Uptime Kuma huendeshwa ndani ya container na hutumia takriban 95 MB ikiwa haifanyi kazi.
  • Hifadhi nakala (backup) za volumes, si containers. Container inaweza kutupwa lakini volume haiwezi. restic backups on a VPS inaelezea ratiba na jaribio la kurejesha data.
  • Funga (pin) image tags kwenye faili ya compose na uzisashe siku unayochagua. Kwa kutumia latest, toleo unalopata kutoka kwa docker compose pull inayofuata ni lile lililotolewa asubuhi hiyo.

VPS ndogo inayoendesha Docker hubaki katika hali nzuri kwa miaka mingi ikiwa namba nne zitabaki katika kiwango kinachotakiwa: bajeti ya kumbukumbu, orodha ya ports zilizofunguliwa, sera ya restart kwenye kila huduma, na nafasi ya diski iliyo wazi. Kila kitu kingine ni Docker ile ile unayoendesha nyumbani.

FAQ

Je, ninahitaji kiasi gani cha RAM ili kuendesha Docker kwenye VPS?

Docker yenyewe haitumii rasilimali nyingi. Daemon na containerd kwa pamoja hutumia takriban 100 MB, na mahitaji mengine hutegemea containers zako. Tenga kwanza sehemu ya seva: 768 MB kwenye mashine ya 2048 MB kwa ajili ya mfumo wa uendeshaji, daemon, na nafasi ya ziada, jambo linalokuachia 1280 MB za kutumia. Database inayotumia 512 MB, reverse proxy ya 128 MB, na programu mbili ndogo zinaweza kutoshea hapo. Pima stack yako mwenyewe kwa kutumia docker stats --no-stream badala ya kuamini takwimu zozote zilizochapishwa.

Je, ninaweza kuendesha Docker kwenye VPS ya 1 GB?

Ndiyo, kwa container moja au mbili ndogo, na ongeza swap file kabla ya kuanza. Takriban nusu ya 1 GB hupotea pindi mfumo wa uendeshaji na Docker daemon vinapoanza, jambo linaloacha nafasi kwa programu ndogo na reverse proxy, lakini si kwa database iliyo chini ya mzigo halisi. Kujenga (build) images kwenye mashine ya ukubwa huo kutafeli au kusababisha mchakato mwingine kusitishwa, hivyo jenga kwingine na uvute (pull) image iliyokamilika.

Je, UFW inalinda Docker container?

Hapana, kwa ports unazochapisha (publish). Docker huandika sheria zake za DNAT na forward, hivyo pakiti inayoelekezwa kwenye port ya container iliyochapishwa hupitishwa moja kwa moja kwenye container badala ya kufikishwa kwa host, na sheria za INPUT zinazosimamiwa na UFW hazioni trafiki hiyo. ufw deny 5432 inaweza kuwa hai wakati port hiyo inajibu maombi kutoka Internet. Chapisha kwenye loopback kwa kutumia 127.0.0.1:5432:5432, acha huduma za ndani zikiwa hazijachapishwa, au chuja trafiki katika chain ya DOCKER-USER.

Je, containers zangu zitajiwasha upya baada ya VPS kuwaka upya (reboot)?

Zitajiwasha tu ikiwa ziliundwa na sera ya restart. Weka restart: unless-stopped kwenye kila huduma, endesha docker compose up -d ili containers ziundwe upya na sera hiyo, na uthibitishe kuwa systemctl is-enabled docker inatoa enabled. Kisha fanya reboot kwa makusudi na uangalie docker compose ps. Sera ya restart ambayo hujawahi kuijaribu si sera ya kuaminika.

Ni mara ngapi ninapaswa kufanya prune ya Docker images?

Mara moja kwa mwezi inatosha kwa seva nyingi ndogo, au wakati wowote docker system df inapoonyesha nafasi inayoweza kurejeshwa ambayo ungependa kuitumia. docker image prune -a na docker builder prune zote ni salama kutumia wakati huduma zinafanya kazi, kwa sababu images na cache zinazotumika hurukwa. Epuka docker system prune --volumes isipokuwa kama unajua vyema ni volumes zipi hazitumiki, kwa sababu inafuta data ya stack yoyote ambayo imesimama kwa wakati huo.