SSD Nodes Learn 🎉 VPS mula $5.50/buwan
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-08-13

Database sa Docker o sa Host: Alin ang Mas Tama?

Alamin kung bakit puwede ang PostgreSQL, MySQL, MongoDB, at Redis sa Docker production, at paano iwasan ang panganib sa volumes, upgrades, backups, at memory limits.

Dapat bang tumakbo ang database sa Docker o sa host?

Patakbuhin ang database sa Docker. Para sa isang application stack sa isang VPS, karaniwang production choice ang containerised PostgreSQL, MySQL, MongoDB, o Redis. Kadalasan, mali ang batayan ng pagtatalo tungkol dito. Ang container ay isang Linux process na may namespaces at cgroups sa paligid nito, hindi isang virtual machine. Kaya walang hypervisor sa pagitan ng database at ng disk. Sa bind mount o local named volume, sa host filesystem napupunta ang mga read at write. Ito rin ang filesystem na gagamitin ng package install.

Ang tunay na gastos ay nasa operasyon. Apat na bagay ang tumutukoy kung maayos ang setup na ito o mauuwi sa mabagal na disaster: kung saan naka-store ang data, kung sino ang may-ari ng directory na iyon, kung paano isasagawa ang major version upgrade, at kung nakapag-restore ka na ba ng backup. Kapag tama ang mga ito, detalye na lamang ang container. Kapag mali, ang container ang malamang mong sisihin.

Pareho ang desisyong ito para sa bawat server database. Gagamit ang mga halimbawa sa ibaba ng PostgreSQL, MySQL, MongoDB, at Redis. Ilalahad ang mga pagkakaiba ayon sa produkto kung mahalaga ang mga ito.

Ano ang aktuwal na binabago ng isang container

Hindi ang storage path, basta nag-mount ka ng isa. Pareho ang kernel, page cache, at filesystem.

May isang tunay na performance trap, at nangyayari ito kapag wala kang mina-mount. Kung walang volume, napupunta ang data directory sa writable layer ng container, na isang overlay filesystem na naka-stack sa image. Mas mabagal ang writes doon, at dine-delete ang buong layer kapag inalis ang container. Dito nanggagaling ang sitwasyong “walang laman ang database ko kaninang umaga.”

Ito ang mga talagang nagbabago:

  • Ang lifecycle. Sinisira ng docker compose down ang container. Kasama nitong nawawala ang anumang wala sa isang volume.
  • Ang version. Ang image tag ang version. Walang apt upgrade sa loob ng database container na mananatili pagkatapos ng susunod na docker compose pull.
  • Ang memory accounting. Ang cgroup limit ay hard wall na ipinapatupad ng kernel, at hindi alam ng database na naroon ito.
  • Ang user. Tumatakbo ang process bilang numeric user id sa loob ng container, at maaaring wala itong pagmamay-ari sa host mo.

Kung saan nakalagay ang data ang nagtatakda ng lahat

May dalawang maayos na opsyon at isang karaniwang pagkakamali.

  • Named volume: pgdata:/var/lib/postgresql/data. Ginagawa ng Docker ang directory sa /var/lib/docker/volumes/<project>_pgdata/_data, at itinatakda ng image entrypoint ang ownership sa unang run. Ito ang default na sagot.
  • Bind mount: /srv/appname/pg:/var/lib/postgresql/data. Ikaw ang pumipili ng path, kaya ikaw ang responsable sa permissions.
  • Walang mount. Tingnan ang nasa itaas. Nasa container ang data.

Sariling paksa ang buong trade-off, at tinatalakay ito ng bind mounts kumpara sa named volumes. Para sa database, ito ang maikling bersyon: gumamit ng named volume maliban kung may partikular kang dahilan para malaman ang host path. Kung gagamit ka ng bind mount, ilagay ito sa stable na lokasyon gaya ng /srv/appname/pg sa halip na sa loob ng project directory na maaaring maabot ng git clean.

May isang mahigpit na limitasyon: huwag ilagay ang database data directory sa NFS (network file system) o sa anumang network mount na hindi mo pa nasusuri ang locking at fsync behaviour nito. Ipinapalagay ng mga database na kapag matagumpay ang fsync, nasa stable storage na ang bytes. Kapag mali ang palagay na ito, magkakaroon ng corruption na maaaring lumitaw makalipas ang ilang linggo.

I-pin ang volume name bago mawala ang volume

Gumagawa ang Compose ng pangalan para sa volume na <project>_<volume>, at ang project name ay nagde-default sa pangalan ng directory. Kaya nakadepende ang identity ng volume sa pangalan ng directory, na madalas napapalitan nang hindi napapansin.

Ilipat ang /srv/app sa /srv/app-old, o palitan ang pangalan ng pgdata key sa compose file, at gagawa ang susunod na docker compose up -d ng bagong volume na walang laman. Ii-initialize ng Postgres ang bagong cluster dito. Healthy ang container, nagsisimula ang application, at nawawala ang lahat ng table. Nasa disk pa rin ang dating volume gamit ang dating pangalan. Ito ang mabuting balita.

docker volume ls
docker volume inspect app_pgdata

I-pin ang mga pangalan para hindi ito mangyari. Itakda nang tahasan ang project name at volume name:

name: myapp

services:
  db:
    image: postgres:17
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
    name: myapp_pgdata

Kung may stray volume nang naglalaman ng iyong data, i-copy ito habang naka-stop ang database:

docker compose stop db
docker run --rm -v app_pgdata:/from -v myapp_pgdata:/to alpine sh -c 'cp -a /from/. /to/'
docker compose start db

Kung magko-copy ka habang tumatakbo ang database, magkakaroon ka ng hindi kumpletong kopya ng mga file na isinusulat pa. I-stop muna ito.

Sino ang may-ari ng data directory

Ang official Postgres, MySQL, at MongoDB images ay nagpapatakbo ng server gamit ang unprivileged user id, karaniwang 999. Kapag root ang user na ginagamit sa pagsisimula ng container, binabago ng entrypoint ang ownership ng data directory para sa user na iyon at pagkatapos ay inaalis ang privileges nito. Kaya karaniwang gumagana agad sa unang pagsubok ang isang empty bind mount.

Nagkakaroon ito ng problema kapag itinakda mo ang user: sa compose file, dahil wala nang natitirang privilege ang entrypoint para ayusin ang anuman. Direktang sinasabi ito ng Postgres:

initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted

Ibang mensahe naman ang ibinibigay kapag umiiral ang data directory pero mali ang mode nito. Mahalagang makilala ang mensaheng ito dahil chmod ang tamang fix, hindi chown:

FATAL:  data directory "/var/lib/postgresql/data" has invalid permissions
DETAIL:  Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).

Sa MongoDB, kapag root ang may-ari ng bind mount, nabibigo ito sa lock file:

Unable to create/open the lock file: /data/db/mongod.lock (Permission denied). Ensure the user executing mongod is the owner of the lock file and has the appropriate permissions.

Ang fix ay gamitin ang chown sa host directory gamit ang numeric id, hindi ang pangalan:

sudo chown -R 999:999 /srv/appname/pg
sudo chmod 700 /srv/appname/pg
ls -ldn /srv/appname/pg

Ang ls -ldn ay nagpi-print ng mga numero sa halip na mga pangalan, at dapat nitong ipakita ang 999 999. Magkaiba at walang kaugnayan ang account na tinatawag na postgres sa iyong host at ang account na tinatawag na postgres sa loob ng image: mga numero ang ikinukumpara ng kernel, at hiwalay na hinahanap ang mga pangalan sa bawat panig. Ipinaliliwanag nang maayos ng kung paano nagmamapa ang PUID at PGID ng mga host user sa isang container ang mapping na ito. Sa rootless Docker o user namespace remapping, nagbabago muli ang mga numero, kaya kunin ang mga id mula sa tumatakbong container sa halip na ipagpalagay na 999.

Iniiwasan ng named volumes ang buong problemang ito sa unang run, dahil gumagawa ang Docker ng empty directory at ang entrypoint ang nagiging may-ari nito.

Mga upgrade: package upgrade kumpara sa pagbabago ng image tag

Sa host, ang apt upgrade ay nagpapalipat sa iyo sa susunod na minor version. Hindi awtomatikong mag-u-upgrade ang iyong distribution sa susunod na major version ng database. Kapag pinili mong mag-upgrade, maaaring mai-install nang sabay ang dalawang set ng binary. Ito mismo ang kailangan ng pg_upgrade.

Sa container, ang tag ang nagsisilbing version, kaya ang upgrade ay pag-edit ng isang linya. Dahil dito, simple ang minor upgrade, ngunit nangangailangan ng procedure ang major upgrade.

Palitan ang postgres:16 ng postgres:17, patakbuhin ang docker compose up -d, at agad na mag-e-exit ang container:

PostgreSQL Database directory appears to contain a database; Skipping initialization
FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.

Walang nasisira. Tumanggi ang mga bagong binary na basahin ang lumang on-disk catalog layout, na nagbabago sa pagitan ng mga major version. Ibalik ang tag sa postgres:16 at muli itong magsisimula. Ang rollback na ito ang tunay na bentahe ng container sa pag-upgrade.

Ang suportadong paraan ay dump at restore. Mas gusto ng PostgreSQL na gawin ang dump gamit ang mas bagong client, kaya patakbuhin ito mula sa bagong image laban sa dati nang tumatakbong lumang server sa compose network:

docker run --rm --network myapp_default -e PGPASSWORD="$POSTGRES_PASSWORD" \
  postgres:17 pg_dumpall -h db -U postgres > /srv/backups/all.sql
ls -lh /srv/backups/all.sql
tail -n 2 /srv/backups/all.sql

Dapat ay hindi bababa sa sampu-sampung kilobyte ang file at nagtatapos sa linyang PostgreSQL database cluster dump complete. Kung ilang daang byte lamang ang file, nabigo ang dump at malapit ka nang mag-delete ng volume nang walang pakinabang. Pagkatapos lamang ng check na iyon:

docker compose down
docker volume rm myapp_pgdata
# edit the compose file: image: postgres:17
docker compose up -d db
docker compose exec -T db psql -U postgres -f /dev/stdin < /srv/backups/all.sql

Magkakaiba ang ibang engine:

  • Ina-upgrade ng MySQL 8 ang sarili nitong data dictionary sa startup, kaya ang minor tag bump ay karaniwang restart lamang. Basahin ang release notes bago lumipat sa ibang release series, at gumawa muna ng dump sa alinmang sitwasyon.
  • Inaasahan ng MariaDB na patakbuhin ang mariadb-upgrade matapos umandar ang server sa bagong version.
  • Kailangang i-upgrade ang MongoDB nang tig-isang major version lamang. Pagkatapos ng bawat hakbang, itakda ang feature compatibility version bago magpatuloy. Kapag lumaktaw sa isang version, tatanggi ang mongod na magsimula at magla-log ng linyang UPGRADE PROBLEM na naglalaman ng featureCompatibilityVersion. Mula MongoDB 7.0, kailangan ng command ang explicit confirmation flag: db.adminCommand({ setFeatureCompatibilityVersion: "8.0", confirm: true }).
  • Madaling nilo-load ng Redis ang mas lumang snapshot file, ngunit hindi nito nilo-load ang mas bagong file. Kaya ang upgrade ay restart lamang, ngunit maaaring mabigong i-load ang data kapag nag-downgrade.

Ang pangkalahatang tuntunin: pinapadali ng container ang downgrade, ngunit hindi nito ginagawang mas madali ang upgrade.

Bakit lumalabas ang database container na may exit code 137?

Pinatay ito ng kernel dahil sa out-of-memory (OOM) killer. Ang 137 ay 128 plus signal 9.

docker compose ps
docker inspect myapp-db-1 | grep -i oomkilled
journalctl -k | tail -n 20

Ipinapakita ng docker compose ps ang Exited (137), nakasaad sa inspect line ang "OOMKilled": true, at may katugmang entry ang kernel log:

Memory cgroup out of memory: Killed process 4711 (postgres) total-vm:2170416kB

Ganito ang mekanismo, at madalas itong ikinagugulat ng mga administrator. Ibinabatay ng PostgreSQL at MySQL ang laki ng kanilang mga buffer sa kabuuang memory na iniuulat ng host. Hindi binabago ng cgroup limit ang numerong iyon para sa kanila. Sa isang host na may 16 GB at limit na 2 GB, kumikilos ang database na parang mayroon itong 16 GB, kaya pinapatay ito ng cgroup bago pa magkaroon ng anumang memory pressure ang host mismo. Kaya hindi sapat ang memory limit lang. Kailangan mo ring tukuyin sa database kung gaano karaming memory ang maaari nitong gamitin:

  • PostgreSQL: itakda ang shared_buffers, at bigyang-pansin ang work_mem. Inilalaan ang work_mem sa bawat sort operation at bawat connection, kaya ang malaking value na minumultiply sa fifty connections ang karaniwang sanhi kung bakit namamatay ang container kapag may load, sa halip na sa startup.
  • MySQL at MariaDB: itakda ang innodb_buffer_pool_size, na may default na 128M. Iwanang naka-off ang innodb_dedicated_server sa isang container, dahil ang buong layunin nito ay awtomatikong magtakda ng laki batay sa natukoy na memory ng machine.
  • MongoDB: tahasang itakda ang laki ng WiredTiger cache sa halip na hayaang tantiyahin ito batay sa memory ng host.
  • Redis: default na unlimited ang maxmemory, kaya patuloy na lumalaki ang Redis hanggang sa pigilan ito ng cgroup. Itakda ang maxmemory nang may sapat na allowance sa ibaba ng container limit at pumili ng maxmemory-policy.

Iniuulat din ng Postgres ang event mula sa sarili nitong panig, at ito ang pares ng mga linyang makikita mo sa log:

LOG:  server process (PID 123) was terminated by signal 9: Killed
LOG:  terminating any other active sessions due to crash of another server process

Kapag pinatay ang isang backend, napipilitan ang lahat ng iba pang backend na mag-restart dahil maaaring maging inconsistent ang shared memory. Nagdudulot ito ng connection storm sa application mo, hindi tahimik na event. Saklaw ng pagtatakda ng memory limits sa Docker Compose ang syntax at ang pagkakaiba ng mem_limit at ng anyong deploy.resources.

Hindi nawawala ang problemang ito sa host. Lumilipat lamang ito. Kung walang cgroup, nakikipag-agawan ang database sa lahat ng iba pang proseso sa machine, at pumipili ng victim ang host OOM killer batay sa score, na maaaring maging sshd. Mas madaling i-operate ang limit na predictably na pumapatay sa database kaysa sa host OOM na nagla-lock sa iyo palabas ng server.

Mga Backup: dump sa loob, backup sa labas

Huwag mag-backup ng tumatakbong database sa pamamagitan ng pagkopya ng data directory nito. Ang file-level copy na ginawa habang nagsusulat ang server ay hindi kumpletong kopya, at malalaman mo lang ito kapag oras na para mag-restore.

Dalawa ang maaasahang paraan: gumamit ng sariling tool ng database para gumawa ng dump habang tumatakbo ito, pagkatapos ay i-backup ang dump; o ihinto ang container at kopyahin ang volume habang naka-stop ito.

docker compose exec -T db pg_dump -U postgres -Fc appdb > /srv/backups/appdb.dump
docker compose exec -T db mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction --all-databases > /srv/backups/mysql.sql
docker compose exec -T db mongodump --archive --gzip --db appdb > /srv/backups/appdb.archive.gz
docker compose exec -T redis redis-cli BGSAVE

Mahalaga ang -T. Kung wala ito, maaaring mag-attach ang docker compose exec ng terminal sa command, at nagdaragdag ang terminal layer ng carriage returns sa output stream. Magkakaroon ng kakaibang error kapag nag-restore ng text dump, at masisira naman nang tuluyan ang binary dump. Tahimik itong pumapalya sa oras ng backup at malakas na lumilitaw makalipas ang isang buwan.

Nagbibigay ang --single-transaction sa mysqldump ng consistent snapshot ng mga InnoDB table nang hindi nilo-lock ang buong server.

Isang file ang sinusulat ng bawat command. Hindi pa ito backup system: walang retention, walang off-box copy, at walang verification. Ibigay ang dump directory sa tool na gumagawa ng tatlong ito, gaya ng restic backups mula sa isang VPS. I-backup ang /srv/backups, hindi ang /var/lib/docker/volumes.

Pagkatapos, patakbuhin ang restore, dahil hindi maituturing na backup ang backup na hindi mo pa na-restore:

docker compose exec -T db createdb -U postgres restore_test
docker compose exec -T db pg_restore -U postgres -d restore_test < /srv/backups/appdb.dump
docker compose exec -T db psql -U postgres -d restore_test -c '\dt'

Dapat ilista ng \dt ang mga table ng application mo. Ang walang laman na resulta o ang Did not find any relations. ay nangangahulugang hindi ang inaakala mo ang dump. I-drop ang restore_test kapag tapos ka na.

Ang command na nagde-delete ng lahat

docker compose down -v.

Ang plain na down ay nag-aalis ng mga container at ng network. Inaalis din ng -v ang bawat named volume na dineklara sa compose file na iyon, pati ang bawat anonymous volume na nakakabit sa mga container na iyon. Walang prompt at walang undo. Ito ang pinakakaraniwang paraan kung paano nasisira ang isang self-hosted database. Karaniwan itong nangyayari habang nagta-troubleshoot ng ibang problema, dahil may forum answer na nagsabing patakbuhin ito.

Apat na bagay ang nakakabawas sa blast radius:

  • I-declare ang database volume bilang external: true. Hindi aalisin ng Compose ang volume na hindi nito pagmamay-ari, kaya hindi ito maaabot ng -v. Gawin ito nang isang beses gamit ang docker volume create myapp_pgdata.
  • Gamitin ang docker compose stop at docker compose start para sa mga regular na restart. Ipinapaliwanag ng down kumpara sa stop sa Compose kung ano ang inaalis ng bawat isa.
  • Panatilihin ang mga dump sa isang host path na nasa labas ng lahat ng volume na mina-manage ng Compose.
  • Huwag kailanman i-paste ang -v mula sa isang troubleshooting answer sa stack na may data na mahalaga sa iyo.

Huwag i-publish ang database port

Inilalagay ng linyang ito ang database sa public internet:

    ports:
      - "5432:5432"

Naka-bind ito sa lahat ng interface. Nire-rewrite ng Docker ang destination ng packet bago pa ito makita ng input rules ng firewall, at nasa input chain ang rules ng ufw. Kaya walang epekto ang ufw deny 5432. Ipinapakita sa kung bakit nababypass ng Docker ang ufw sa mga published port ang pagdaan ng packet sa chain.

Nakaka-access ang application sa parehong compose project sa database gamit ang service name sa compose network, kaya hindi nito kailangan ng published port. Tanggalin ang block. Kung kailangan ng client sa host, i-bind lamang ito sa loopback:

    ports:
      - "127.0.0.1:5432:5432"

Suriin kung ano talaga ang nakikinig:

sudo ss -ltnp | grep 5432

Ang 127.0.0.1:5432 ang gusto mo. Ibig sabihin ng 0.0.0.0:5432, maaaring subukan ng kahit sino ang iyong password.

Ano ang dapat patakbuhin at saan

Isang application sa isang VPS. Gumamit ng container. Magtakda ng named volume na may fixed na pangalan, huwag mag-publish ng port, magtakda ng memory limit na tugma sa database settings, at gumawa ng nightly dump sa host path na kinokolekta ng restic. Magsimula sa malinis na Docker install sa isang VPS at ilagay ang buong stack sa isang compose file na kino-commit mo. Malinaw ang pakinabang: nagiging linya sa git na maaaring i-review ang database version.

Isang host na nagpapatakbo ng ilang serbisyo. Gumamit ng mga container, na may tig-isang database bawat application, hindi isang shared server para sa lahat. Kapag shared server ang gamit, nakatali ang bawat application sa iisang upgrade schedule, at ang isang runaway query ay maaaring magdulot ng outage sa lahat. Bigyan ang bawat container ng sarili nitong memory limit upang ang maling query ay manatiling limitado sa application na pinagmulan nito. Bahagyang mas malaki ang disk cost ng ilang maliliit na Postgres instance, pero mas kaunti ang coordination na kailangan.

Ang database ang pangunahing produkto. Patakbuhin ito sa host gamit ang package repository ng vendor, o gumamit ng managed service. Kailangang sabay na naka-install ang dalawang major version ng binaries para sa pg_upgrade. Ibinibigay ito ng mga package, samantalang hindi ito magagawa ng isang single-version image. Mas madali ang replication at point-in-time recovery gamit ang WAL (write-ahead log) archiving kapag ang database ang nagmamay-ari sa machine at mga disk nito. Piliin ang simple at subok na paraan para sa system na magpapadala sa iyo ng page sa 03:00.

Maliit ang application. Isaalang-alang ang hindi paggamit ng server database. Ang isang single-writer web application sa isang VPS ay madalas na mas angkop sa SQLite sa production sa isang VPS, kung saan isang file lamang ang backup at library version ang upgrade path.

FAQ

Ligtas bang magpatakbo ng production database sa Docker?

Oo, para sa application stack na nasa iisang server. Ang container ay isang Linux process na may namespaces at cgroups sa paligid nito. Kapag may naka-mount na volume, sa parehong host filesystem nagsusulat ang database na gagamitin nito kung ini-install mo ito mula sa package. Operational ang mga panganib, hindi tungkol sa bilis: volume na walang naka-pin na pangalan, bind mount na pagmamay-ari ng maling user id, restore na hindi mo pa nasusubukan, at docker compose down -v. Kapag naayos ang apat na ito, maayos gamitin ang container. Lumipat sa host install kapag ang database ang pangunahing workload at kailangan mo ng pg_upgrade, replication, o point in time recovery.

Dapat ba akong gumamit ng bind mount o named volume para sa data ng database?

Gumamit ng named volume maliban kung may partikular kang dahilan para malaman ang host path. Ginagawa ng Docker ang directory, at itinatakda ng image entrypoint ang ownership sa unang pagsisimula. Kaya hindi lumilitaw ang permission problem. I-pin ang volume gamit ang tahasang name: o markahan ito bilang external: true. Kung hindi, ang pagpapalit ng pangalan ng project directory ay tahimik na gagawa ng bagong walang-lamang volume at walang-lamang database. Ayos ang bind mount kung gagawin mong pagmamay-ari ng numeric user id na ginagamit ng image ang host directory. Ang user id na ito ay 999 para sa official Postgres, MySQL, at MongoDB images. I-verify ito gamit ang ls -ldn, dahil ipinapakita ng ls -l ang pangalan ng host para sa numerong iyon, at walang saysay ang pangalang iyon sa loob ng container.

Ano ang dine-delete ng docker compose down -v?

Inaalis nito ang mga container at network tulad ng karaniwang down. Ang -v ay nag-aalis din ng bawat named volume na dineklara sa compose file na iyon, pati ng bawat anonymous volume na naka-attach sa mga container na iyon. Kasama rito ang database. Walang confirmation prompt at walang recovery. Hindi inaalis ang mga volume na minarkahan bilang external: true. Ito ang pangunahing dahilan kung bakit dapat markahan bilang external ang database volume. Para sa karaniwang restart, gamitin ang docker compose stop at docker compose start sa halip.

Paano ko ia-upgrade ang PostgreSQL sa bagong major version sa Docker?

Gumawa ng dump at i-restore ito. Kapag pinalitan ang postgres:16 ng postgres:17 at ni-restart, magkakaroon ng FATAL: database files are incompatible with server na may DETAIL line na naglilista sa parehong version. Hindi mababasa ng mga bagong binary ang lumang catalog layout. Walang nasisira. Ibalik ang lumang tag at muli itong magsisimula. Gumawa ng pg_dumpall gamit ang client ng bagong version laban sa tumatakbong lumang container. Tiyaking nagtatapos ang file sa PostgreSQL database cluster dump complete. Pagkatapos, patakbuhin ang bagong tag sa walang-lamang volume at i-load ang dump. Para sa minor upgrade sa loob ng iisang major version, pull at restart lang ang kailangan.

Bakit nag-e-exit ang database container ko na may code 137?

Ang 137 ay 128 dagdag sa signal 9. Ibig sabihin, puwersahang pinatay ang process. Patakbuhin ang docker inspect <container> | grep -i oomkilled. Ang halagang true ay nangangahulugang naabot ng container ang cgroup memory limit nito. Karaniwang nangyayari ito dahil binabasa ng PostgreSQL at MySQL ang kabuuang memory mula sa host at hindi nakikita ang limit ng container. Kaya nagpaplano ang mga ito para sa 16 GB habang nasa loob lamang ng 2 GB. Itakda ang shared_buffers at work_mem, o ang innodb_buffer_pool_size, upang umangkop sa limit na ibinigay mo sa container. Suriin ang journalctl -k para sa katugmang Memory cgroup out of memory line upang makumpirma kung aling process ang pinili ng kernel.