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

Je, database inapaswa kuendeshwa kwenye Docker au host?

Kutumia Docker kwa PostgreSQL, MySQL, MongoDB au Redis ni salama kwa uzalishaji. Jifunze jinsi ya kudhibiti volumes, backups, upgrades na mipaka ya kumbukumbu ili kuepuka hatari.

Je, database inapaswa kuendeshwa kwenye Docker au kwenye host?

Endesha database kwenye Docker. Kwa stack moja ya programu kwenye VPS moja, PostgreSQL, MySQL, MongoDB au Redis iliyo kwenye container ni chaguo la kawaida la uzalishaji (production), na mjadala ambao watu wanakuwa nao kuhusu hili mara nyingi si sahihi. Container ni mchakato (process) wa Linux wenye namespaces na cgroups, si mashine ya mtandaoni (virtual machine), kwa hivyo hakuna hypervisor kati ya database na diski. Kwa kutumia bind mount au local named volume, usomaji na uandikaji wa data hufanyika kwenye filesystem ya host, ile ile ambayo ingetumika kwa usakinishaji wa kifurushi (package install).

Gharama halisi ni ya kiutendaji. Mambo manne huamua kama usanidi huu ni mzuri au ni janga la polepole: mahali data ilipo, nani anayemiliki saraka (directory) hiyo, jinsi upgrade ya toleo kuu (major version) inavyofanyika, na kama umewahi kurejesha backup. Ukizingatia hayo, container inakuwa ni maelezo tu ya kiufundi. Ukikosea hayo, container ndiyo kitu utakachokilaumu.

Huu ni uamuzi uleule kwa kila database ya seva. Mifano hapa chini inatumia PostgreSQL, MySQL, MongoDB na Redis, na tofauti mahususi za bidhaa hizo zimeainishwa pale zinapokuwa na umuhimu.

Kile ambacho container hubadilisha kihalisi

Sio njia ya hifadhi (storage path), mradi tu uweke mount. Kernel ni ile ile, page cache ni ile ile, na filesystem ni ile ile.

Kuna mtego mmoja wa utendaji (performance trap), nao ni pale unaposhindwa kuweka mount yoyote. Bila volume, saraka ya data huenda kwenye safu ya kuandika (writable layer) ya container, ambayo ni overlay filesystem iliyopangwa juu ya image. Uandikaji hapo huwa polepole, na safu nzima hufutwa wakati container inapoondolewa. Hapo ndipo tatizo la "database yangu ilikuwa tupu asubuhi ya leo" linapotokea.

Mambo yanayobadilika kihalisi:

  • Mzunguko wa maisha (lifecycle). docker compose down huharibu container. Kila kitu ambacho hakikuwa kwenye volume hupotea pamoja nayo.
  • Toleo (version). Image tag ndiyo toleo. Hakuna apt upgrade ndani ya database container inayoweza kunusurika baada ya docker compose pull inayofuata.
  • Uhasibu wa kumbukumbu (memory accounting). Kikomo cha cgroup ni ukuta mgumu unaotekelezwa na kernel, na database haijui kama upo.
  • Mtumiaji (user). Mchakato (process) huendeshwa kama namba ya kitambulisho cha mtumiaji (numeric user id) ndani ya container, ambayo inaweza isimiliki chochote kwenye host yako.

Mahali data inapohifadhiwa huamua kila kitu

Kuna chaguo mbili nzuri na kosa moja la kawaida.

  • Named volume: pgdata:/var/lib/postgresql/data. Docker hutengeneza saraka katika /var/lib/docker/volumes/<project>_pgdata/_data, na entrypoint ya image huweka umiliki wakati wa uendeshaji wa kwanza. Hili ndilo jibu chaguo-msingi.
  • Bind mount: /srv/appname/pg:/var/lib/postgresql/data. Unachagua njia (path), kwa hivyo unawajibika na tatizo la ruhusa (permissions).
  • Kutotumia mount kabisa. Tazama hapo juu. Data inabaki ndani ya container.

Mjadala kamili wa faida na hasara ni mada inayojitegemea, na bind mounts dhidi ya named volumes inaelezea hilo. Kwa database, maelezo mafupi ni: tumia named volume isipokuwa kama una sababu maalum ya kujua njia ya host, na ukiamua kutumia bind mount, iweke mahali thabiti kama /srv/appname/pg badala ya ndani ya saraka ya mradi ambapo git clean inaweza kuifikia.

Kikomo kimoja kigumu: usiweke saraka ya data ya database kwenye NFS (network file system) au mount yoyote ya mtandao ambayo tabia yake ya locking na fsync hujaijaribu. Database huchukulia kuwa fsync iliyofanikiwa inamaanisha kuwa bytes ziko kwenye hifadhi thabiti. Dhana hiyo inapokuwa si sahihi, unapata uharibifu wa data unaojitokeza wiki kadhaa baadaye.

Bandika jina la volume kabla ya volume kupotea

Compose huipa volume jina <project>_<volume>, na jina la mradi hutokana na jina la saraka (directory) kwa chaguo-msingi. Kwa hivyo, utambulisho wa volume hutegemea jina la saraka, jambo ambalo watu hubadilisha bila kufikiria.

Ukihamisha /srv/app kwenda /srv/app-old, au ukibadilisha jina la ufunguo wa pgdata katika faili ya compose, amri ya docker compose up -d inayofuata itatengeneza volume mpya tupu. Postgres huanzisha cluster mpya ndani yake. Container inakuwa katika hali nzuri, programu inaanza, na kila jedwali (table) linapotea. Habari njema ni kwamba volume ya zamani bado ipo kwenye diski kwa jina lake la zamani.

docker volume ls
docker volume inspect app_pgdata

Bandika majina ili jambo hili lisitokee. Weka jina la mradi na jina la volume kwa uwazi:

name: myapp

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

volumes:
  pgdata:
    name: myapp_pgdata

Ikiwa volume iliyopotea tayari ina data zako, nakili data hizo huku database ikiwa imesimamishwa:

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

Ukinakili data huku database ikiwa inaendelea kufanya kazi, utapata nakala iliyoharibika ya faili zilizokuwa zikiandikwa. Isimamishe kwanza.

Nani anamiliki saraka ya data

Picha rasmi za Postgres, MySQL na MongoDB huendesha seva zao kama mtumiaji asiye na upendeleo (unprivileged user), kwa kawaida 999. Wakati container inapoanza kama root, entrypoint hubadilisha umiliki wa saraka ya data kwenda kwa mtumiaji huyo na kisha huacha upendeleo (drop privileges). Hii ndiyo sababu bind mount tupu kwa kawaida hufanya kazi katika jaribio la kwanza.

Hii huharibika pale unapoweka user: kwenye faili ya compose, kwa sababu wakati huo entrypoint haina upendeleo wowote wa kurekebisha jambo lolote. Postgres husema hivyo moja kwa moja:

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

Saraka ya data iliyopo ikiwa na mode isiyo sahihi hutoa ujumbe tofauti, na ujumbe huu unastahili kutambuliwa kwa sababu suluhisho ni chmod, si chown:

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

MongoDB kwenye bind mount inayomilikiwa na root hushindwa kwenye faili ya lock:

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.

Suluhisho ni kufanya chown kwenye saraka ya host kwa kutumia namba ya kitambulisho (numeric id), si jina:

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

ls -ldn huchapisha namba badala ya majina, na inapaswa kuonyesha 999 999. Akaunti inayoitwa postgres kwenye host yako na akaunti inayoitwa postgres ndani ya image hazihusiani: kernel hulinganisha namba, na majina hutafutwa kando kila upande. jinsi PUID na PGID zinavyopanga watumiaji wa host ndani ya container hufafanua upangaji huo vizuri. Chini ya Docker isiyo na root (rootless Docker) au user namespace remapping, namba hubadilika tena, kwa hivyo soma vitambulisho (ids) kutoka kwenye container inayofanya kazi badala ya kudhani ni 999.

Named volumes hufanya sehemu hii yote kutoweka katika uendeshaji wa kwanza, kwa sababu Docker hutengeneza saraka tupu na entrypoint huimiliki.

Uboreshaji: uboreshaji wa kifurushi dhidi ya mabadiliko ya image tag

Kwenye host, apt upgrade hukupeleka kwenye toleo dogo (minor version). Distribution yako haitaruka toleo kubwa (major version) la database bila wewe kujua, na unapoamua kuruka, seti zote mbili za binaries zinaweza kusakinishwa kwa wakati mmoja, jambo ambalo ndilo hasa pg_upgrade inahitaji.

Kwenye container, tag ndiyo toleo, kwa hivyo uboreshaji ni kuhariri mstari mmoja tu. Hii hufanya uboreshaji mdogo kuwa rahisi na uboreshaji mkubwa kuwa utaratibu maalum.

Badilisha postgres:16 kuwa postgres:17, endesha docker compose up -d, na container itazima mara moja:

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.

Hakuna kinachoharibika. Binaries mpya hukataa kusoma muundo wa zamani wa catalog uliopo kwenye diski, ambao hubadilika kati ya matoleo makubwa. Rudisha tag kuwa postgres:16 na itaanza tena. Rollback hiyo ndiyo faida moja ya kweli ya uboreshaji ambayo containers hukupa.

Njia inayoungwa mkono ni dump na restore. PostgreSQL hupendelea dump ichukuliwe na client mpya zaidi, kwa hivyo iendeshe kutoka kwenye image mpya dhidi ya server ya zamani inayoendelea kufanya kazi kwenye 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

Faili linapaswa kuwa na ukubwa wa makumi ya kilobytes angalau na liishie na mstari unaosomeka PostgreSQL database cluster dump complete. Faili la bytes chache mia chache linamaanisha kuwa dump imefeli na unakaribia kufuta volume bila sababu. Fanya hivi tu baada ya ukaguzi huo:

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

Injini nyingine hutofautiana:

  • MySQL 8 huboresha data dictionary yake yenyewe wakati wa kuanza (startup), kwa hivyo kubadilisha tag kidogo kwa kawaida ni restart tu. Soma maelezo ya toleo (release notes) kabla ya kuruka kati ya mfululizo wa matoleo, na chukua dump kwanza kwa vyovyote vile.
  • MariaDB inatarajia mariadb-upgrade iendeshwe baada ya server kuwaka kwenye toleo jipya.
  • MongoDB lazima iboreshwe toleo moja kubwa kwa wakati mmoja, na baada ya kila hatua unaweka feature compatibility version kabla ya kuendelea. Kuruka toleo kunamaanisha mongod itakataa kuanza na kuandika kwenye log mstari wa UPGRADE PROBLEM unaotaja featureCompatibilityVersion. Kuanzia MongoDB 7.0 na kuendelea, amri hiyo inahitaji flag ya uthibitisho wa wazi: db.adminCommand({ setFeatureCompatibilityVersion: "8.0", confirm: true }).
  • Redis hupakia faili za snapshot za zamani bila shida lakini si zile mpya, kwa hivyo uboreshaji ni restart na kushusha toleo (downgrade) kunaweza kufeli kupakia data.

Kanuni ya jumla: container hurahisisha kushusha toleo na haifanyi uboreshaji kuwa rahisi zaidi.

Kwa nini container yangu ya database inazima na kutoa code 137?

Hii hutokea kwa sababu kernel's out of memory (OOM) killer imeizima. 137 ni jumla ya 128 na signal 9.

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

docker compose ps inaonyesha Exited (137), mstari wa inspect unasomeka "OOMKilled": true, na log ya kernel ina ujumbe unaolingana:

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

Huu ndio utaratibu wake, na unawashangaza watu wengi. PostgreSQL na MySQL hupanga ukubwa wa buffers zao kulingana na kumbukumbu ya jumla ya seva (host). Kikomo cha cgroup hakibadilishi namba hiyo kwa programu hizo. Kwenye seva ya 16 GB yenye kikomo cha 2 GB, database hupanga mipango yake kama ina 16 GB, na cgroup huizima muda mrefu kabla seva yenyewe haijapata shinikizo la kumbukumbu. Kwa hiyo, kuweka kikomo cha kumbukumbu pekee hakutoshi. Lazima uieleze database kile ilichonacho:

  • PostgreSQL: weka shared_buffers, na uzingatie work_mem. work_mem hutengwa kwa kila operesheni ya sort kwa kila muunganisho (connection), hivyo thamani kubwa ikizidishwa na miunganisho hamsini ndiyo sababu ya kawaida ya container kufa wakati wa mzigo mkubwa badala ya wakati wa kuanza.
  • MySQL na MariaDB: weka innodb_buffer_pool_size, ambayo thamani yake ya kawaida ni 128M. Zima innodb_dedicated_server ukiwa kwenye container, kwa sababu kazi yake yote ni kujipanga kulingana na kumbukumbu inayotambuliwa kwenye mashine.
  • MongoDB: weka ukubwa wa WiredTiger cache waziwazi badala ya kuiacha ikisie kutoka kwenye kumbukumbu ya seva.
  • Redis: maxmemory haina kikomo kwa kawaida, hivyo Redis hukua hadi cgroup itakapoisimamisha. Weka maxmemory kwa kiwango cha chini ya kikomo cha container na uchague maxmemory-policy inayofaa.

Postgres pia huripoti tukio hili kwa upande wake, na jozi hii ya mistari ndiyo utakayopata kwenye 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

Backend moja ikizimwa hulazimisha backend nyingine zote kuanza upya, kwa sababu kumbukumbu iliyoshirikiwa (shared memory) inaweza kuwa haiko sawa. Hiyo ni dhoruba ya miunganisho kwa programu yako, si tukio dogo. kuweka mipaka ya kumbukumbu katika Docker Compose inaelezea sintaksia na tofauti kati ya mem_limit na mfumo wa deploy.resources.

Hakuna kati ya haya yanayopotea kwenye seva. Yanahamia tu. Bila cgroup, database hushindana na kila kitu kingine kwenye seva, na OOM killer ya seva huchagua mwathiriwa kwa alama, jambo ambalo linaweza kuathiri hata sshd. Kikomo kinachozima database kwa njia inayotabirika ni rahisi kusimamia kuliko OOM ya seva inayoweza kukufungia nje.

Backups: fanya dump ndani, hifadhi nje

Usihifadhi database inayofanya kazi kwa kunakili saraka yake ya data. Nakala ya kiwango cha faili inayochukuliwa wakati seva inaandika data husababisha nakala iliyoharibika (torn copy), na utagundua hilo wakati wa kurejesha data.

Kuna njia mbili za kuaminika: fanya dump kwa kutumia zana ya database yenyewe wakati inafanya kazi na uhifadhi dump hiyo, au simamisha container na unakili volume wakati haifanyi kazi (cold copy).

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

-T ni muhimu. Bila hiyo, docker compose exec inaweza kuunganisha terminal kwenye amri, na safu ya terminal huongeza carriage returns kwenye mtiririko wa pato. Dump ya maandishi basi itarejeshwa ikiwa na makosa ya ajabu na dump ya binary itakuwa imeharibika. Inashindwa kimya kimya wakati wa kuhifadhi na kwa kelele mwezi mmoja baadaye.

--single-transaction huipa mysqldump snapshot thabiti ya meza za InnoDB bila kufunga seva nzima.

Amri hizo huandika faili moja kila moja. Hizo si mfumo wa kuhifadhi data: hakuna uhifadhi wa muda mrefu (retention), hakuna nakala nje ya seva, na hakuna uthibitishaji. Kabidhi saraka ya dump kwa zana inayofanya mambo hayo yote matatu, ambayo ndiyo kazi ya restic backups kutoka VPS. Hifadhi /srv/backups, si /var/lib/docker/volumes.

Kisha fanya urejeshaji, kwa sababu backup ambayo hujawahi kuirejesha si backup:

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'

\dt inapaswa kuorodhesha meza za programu yako. Matokeo tupu, au Did not find any relations., inamaanisha dump si ile unayofikiri. Futa restore_test ukimaliza.

Amri inayofuta kila kitu

docker compose down -v.

down ya kawaida huondoa container na mtandao. -v huondoa pia kila volume yenye jina iliyotangazwa kwenye faili hiyo ya compose, pamoja na kila volume isiyo na jina iliyounganishwa kwenye container hizo. Hakuna onyo la kuthibitisha na hakuna njia ya kutendua. Hii ndiyo njia ya kawaida zaidi ya kufuta database inayojiendesha (self-hosted), na mara nyingi hutokea wakati wa kutatua tatizo lisilohusiana, kwa sababu jibu kwenye jukwaa (forum) liliagiza kuiendesha.

Mambo manne hupunguza madhara ya kitendo hiki:

  • Tangaza volume ya database kama external: true. Compose haitaondoa volume ambayo haimiliki, kwa hivyo -v haiwezi kuifikia. Unaitengeneza mara moja kwa kutumia docker volume create myapp_pgdata.
  • Tumia docker compose stop na docker compose start kwa ajili ya kuanzisha upya (restart) za kawaida. down dhidi ya stop katika Compose inaelezea kwa kina kile ambacho kila moja huondoa.
  • Hifadhi nakala (dumps) kwenye njia ya host (host path) iliyo nje ya kila volume inayodhibitiwa na compose.
  • Usiwahi kubandika -v kutoka kwenye jibu la utatuzi wa matatizo kwenye stack inayoshikilia data unayoiangalia.

Usichapishe port ya database

Mstari huu unaweka database yako kwenye Internet ya umma:

    ports:
      - "5432:5432"

Hii inafunga (bind) kwenye kila interface. Docker huchapisha port kwa kubadilisha mahali pa mwisho pa pakiti (packet's destination) kabla ya sheria za input za firewall yako kuiona, na sheria za ufw ziko kwenye input chain, kwa hivyo ufw deny 5432 haifanyi kazi yoyote. kwa nini ports zilizochapishwa na Docker hupita ufw inaonyesha jinsi chain inavyopitiwa.

Programu iliyo kwenye compose project moja hufikia database kwa kutumia jina la huduma kwenye compose network, kwa hivyo haihitaji port iliyochapishwa. Futa block hiyo. Ikiwa unataka client iliyo kwenye host, ifunge kwenye loopback pekee:

    ports:
      - "127.0.0.1:5432:5432"

Angalia nini kinachosikiliza (listening) kwa sasa:

sudo ss -ltnp | grep 5432

127.0.0.1:5432 ndicho unachotaka. 0.0.0.0:5432 inamaanisha mtu yeyote anaweza kujaribu nenosiri lako.

Nini cha kuendesha wapi

Programu moja kwenye VPS moja. Tumia container. Tumia named volume yenye jina maalum, usichapishe port yoyote, weka kikomo cha kumbukumbu (memory limit) kinacholingana na mipangilio ya database, na ufanye dump ya kila usiku kwenye njia ya host ambayo restic itakusanya. Anza kutoka usakinishaji safi wa Docker kwenye VPS na uhifadhi stack nzima kwenye faili moja ya compose unayoiweka kwenye git. Faida yake ni dhahiri: toleo la database linakuwa mstari unaoweza kukaguliwa kwenye git.

Host inayoendesha huduma kadhaa. Tumia containers, database moja kwa kila programu, si seva moja inayoshirikiwa na zote. Seva inayoshirikiwa huifunga kila programu kwenye ratiba moja ya uboreshaji, na query moja mbaya inaweza kusababisha huduma zote kukatika. Ipe kila container kikomo chake cha kumbukumbu ili query mbaya iishie kwenye programu iliyoizalisha. Mifano kadhaa midogo ya Postgres inagharimu disk kidogo zaidi na inahitaji uratibu mdogo sana.

Database ndiyo bidhaa yenyewe. Iendeshe kwenye host kutoka kwenye hazina ya vifurushi (package repository) ya muuzaji, au lipia huduma inayodhibitiwa (managed service). pg_upgrade inahitaji matoleo makuu yote mawili ya binaries yawe yamesakinishwa kwa wakati mmoja, jambo ambalo vifurushi hukupa lakini image ya toleo moja haikupi. Uigaji (replication) na urejeshaji wa data kulingana na wakati (point in time recovery) kwa kutumia WAL (write ahead log) archiving ni rahisi zaidi wakati database inamiliki mashine na disk zake. Chagua njia ya kawaida na inayotabirika kwa mfumo utakaokupigia simu saa 03:00 usiku.

Programu ni ndogo. Fikiria kutotumia database ya seva kabisa. Programu ya wavuti yenye mwandishi mmoja (single-writer) kwenye VPS moja mara nyingi hufanya kazi vizuri zaidi kwa SQLite katika mazingira ya production kwenye VPS, ambapo backup ni faili moja na njia ya uboreshaji ni toleo la maktaba (library version).

FAQ

Je, ni salama kuendesha database ya uzalishaji (production) ndani ya Docker?

Ndiyo, kwa stack ya programu inayotumia seva moja. Container ni mchakato wa Linux wenye namespaces na cgroups, kwa hivyo ukiwa na volume iliyopachikwa (mounted), database huandika kwenye mfumo wa faili wa seva (host filesystem) uleule ambao ingeutumia kama ungeiweka kupitia package. Hatari zake ni za kiutendaji zaidi kuliko za kasi: volume ambayo jina lake halijafungwa, bind mount inayomilikiwa na user id isiyo sahihi, urejeshaji (restore) ambao hujawahi kuujaribu, na docker compose down -v. Tatua hayo manne na container itakuwa salama. Hamia kwenye usakinishaji wa moja kwa moja kwenye seva (host install) wakati database ndiyo kazi kuu na unahitaji pg_upgrade, replication, au point in time recovery.

Je, nitumie bind mount au named volume kwa data za database?

Tumia named volume isipokuwa kama una sababu maalum ya kujua njia (path) ya seva. Docker hutengeneza saraka (directory) na entrypoint ya image huweka umiliki wakati wa kuanza kwa mara ya kwanza, kwa hivyo tatizo la ruhusa (permission) halijitokezi. Funga volume hiyo kwa name: maalum au iweke alama kama external: true, vinginevyo kubadili jina la saraka ya mradi kutatengeneza volume mpya tupu na database tupu bila taarifa. Bind mount inafaa ikiwa utafanya chown kwenye saraka ya seva kwa numeric user id ambayo image inaitumia, ambayo ni 999 kwa image rasmi za Postgres, MySQL na MongoDB. Iithibitishe kwa ls -ldn, kwa sababu ls -l huonyesha jina la seva yako kwa namba hiyo na jina hilo halina maana ndani ya container.

docker compose down -v hufuta nini?

Huondoa container na mtandao kama vile down ya kawaida, na -v huongeza kuondoa kila named volume iliyotangazwa kwenye faili hilo la compose pamoja na kila anonymous volume iliyounganishwa na container hizo. Hiyo inajumuisha database. Hakuna kidokezo cha uthibitisho na hakuna njia ya kurejesha data. Volume zilizowekwa alama external: true haziondolewi, ambayo ndiyo sababu kuu ya kuweka alama ya database volume kama external. Kwa kuanzisha upya (restart) ya kawaida, tumia docker compose stop na docker compose start badala yake.

Ninawezaje kupandisha toleo (upgrade) la PostgreSQL hadi toleo jipya kuu (major version) ndani ya Docker?

Fanya dump na restore. Kubadili postgres:16 kuwa postgres:17 na kuanzisha upya kutatoa FATAL: database files are incompatible with server yenye mstari wa DETAIL unaotaja matoleo yote mawili, kwa sababu binaries mpya hazitasoma mpangilio wa zamani wa catalog. Hakuna kinachoharibika: rudisha tag ya zamani na itaanza. Chukua pg_dumpall kwa kutumia client ya toleo jipya dhidi ya container ya zamani inayofanya kazi, thibitisha faili linaishia na PostgreSQL database cluster dump complete, kisha leta tag mpya kwenye volume tupu na upakie dump hiyo. Maboresho madogo (minor upgrades) ndani ya toleo moja kuu yanahitaji tu pull na restart.

Kwa nini container yangu ya database inajifunga na kutoa code 137?

137 ni 128 jumlisha signal 9, kwa hivyo kuna kitu kimeua mchakato huo moja kwa moja. Endesha docker inspect <container> | grep -i oomkilled; thamani ya true inamaanisha container imefikia kikomo chake cha kumbukumbu (memory limit) cha cgroup. Sababu ya kawaida ni kwamba PostgreSQL na MySQL husoma jumla ya kumbukumbu kutoka kwa seva na hawaoni kikomo cha container, kwa hivyo hupanga kutumia 16 GB wakati wako ndani ya 2 GB. Weka shared_buffers na work_mem, au innodb_buffer_pool_size, ili kulingana na kikomo ulichokipa container. Angalia journalctl -k kwa mstari wa Memory cgroup out of memory unaolingana ili kuthibitisha ni mchakato gani kernel ilichagua.