
Docker Compose контейнер асахыг бэлэн болсонтой бүү андуур: healthcheck нэм

Docker Compose-д `depends_on` нь өгөгдлийн сангийн контейнерийг аппын өмнө эхлүүлдэг ч холболт хүлээн авахад бэлэн болсныг дангаараа хүлээдэггүйг Docker-ийн асаах дарааллын заавар тайлбарладаг. Тиймээс эхлэх дараалал зөв байсан ч аппын анхны өгөгдлийн сангийн холболт бүтэлгүйтэж болно.
Шийдэл нь өгөгдлийн сангийн үйлчилгээнд холболтын бэлэн байдлыг хэмжих `healthcheck` нэмээд, аппын `depends_on` хэсэгт `condition: service_healthy` заах юм. Compose шалгалт амжилттай болж `db` эрүүл төлөвт орсны дараа хамааралтай аппыг эхлүүлнэ. Энэ нөхцөл зөвхөн эхлэх үеийн хамаарлыг зохицуулдаг тул апп ажиллаж байх үеийн тасалдлыг мөн тооцох хэрэгтэй.
Контейнер ажиллаж байхад холболт яагаад бүтэлгүйтдэг вэ?
Контейнерийн үндсэн процесс асах, PostgreSQL холболт хүлээн авах хоёр өөр үе шат. Өгөгдлийн сан эхлэх ажлаа гүйцээж байх хооронд контейнер ажиллаж буй мэт харагдавч хүсэлтэд хариулах боломжгүй байж болно. Апп тэр завсарт холбогдохоор оролдвол алдаа нь үйлчилгээний дарааллаас бус, бэлэн байдлыг шалгаагүйгээс үүснэ.
`depends_on: [db]` гэсэн богино бичлэг хамаарлыг зарлахад хангалттай боловч `db`-гийн эрүүл төлөвийг шаарддаггүй. Урт бичлэгийн `condition: service_healthy` нь `db` дээр бодит шалгалт зарласан үед хэрэгтэй. Шалгалтын команд аппад шаардлагатай хамгийн бага нөхцөлийг хэмжих ёстой: энэ жишээнд PostgreSQL TCP холболт хүлээн авч эхэлсэн эсэхийг шалгана.
PostgreSQL болон аппын тохиргоог нэгтгэх нь

Дараах нь `compose.yaml` файлд ашиглаж болох нэг мөрийн YAML жишээ. Аппын Dockerfile төслийн үндсэн хавтаст байна, мөн апп `DB_HOST`, `DB_USER`, `DB_NAME`, `DB_PASSWORD` хувьсагчийг уншдаг гэж нөхцөлдөнө. Өөрийн аппын орчны хувьсагчийн нэрийг тааруулж, `replace_me` гэсэн жишээ нууц үгийг солино.
services: {db: {image: "postgres:16", environment: {POSTGRES_USER: app, POSTGRES_DB: app, POSTGRES_PASSWORD: replace_me}, healthcheck: {test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U $${POSTGRES_USER} -d $${POSTGRES_DB} -t 2"], interval: 5s, timeout: 3s, retries: 5, start_period: 20s}}, app: {build: ., environment: {DB_HOST: db, DB_USER: app, DB_NAME: app, DB_PASSWORD: replace_me}, depends_on: {db: {condition: service_healthy}}}}
`pg_isready` нь `db` контейнер дотроос `127.0.0.1` хаягаар PostgreSQL-ийн холболтыг шалгана. PostgreSQL-ийн `pg_isready` заавар сервер холболт хүлээж байвал `0`, эхлэх явцдаа татгалзвал `1`, хариу өгөхгүй бол `2` төлөв буцаадгийг тодорхойлдог. Харин апп өөрийн контейнерээс өгөгдлийн санд холбогдохдоо `127.0.0.1` бус, Compose дахь `db` үйлчилгээний нэрийг хаяг болгон ашиглана.
`$${POSTGRES_USER}` болон `$${POSTGRES_DB}` дэх давхар долларын тэмдэг Compose файлыг уншихдаа хувьсагчийг орлуулахгүй үлдээнэ. Ингэснээр шалгалт контейнер дотор ажиллах үед shell нь `POSTGRES_USER` болон `POSTGRES_DB`-ийн утгыг авна. `CMD-SHELL` сонгосон нь командыг shell-ээр ажиллуулж, тэр хувьсагчдыг задлах боломж олгож байгаа хэрэг.
`pg_isready` амжилттай болсон ч аппын нууц үг зөв, хүснэгтүүд үүссэн, migration дууссан гэсэн баталгаа болохгүй. PostgreSQL-ийн заавраар серверийн төлөвийг мэдэхийн тулд хэрэглэгч эсвэл өгөгдлийн сангийн нэр зөв байх албагүй. Хэрэв аппад migration зайлшгүй хэрэгтэй бол түүнийг өөрийн эхлэх ажиллагаанд тусад нь зохицуулна.
Шалгалтын хугацаанууд юу удирддаг вэ?
Compose үйлчилгээний лавлах `healthcheck`-ийн `test`, `interval`, `timeout`, `retries`, `start_period` талбаруудыг тодорхойлдог. Жишээнд өгсөн хугацаа, оролдлогын тоо нь тохируулж үзэх эхлэл болохоос бүх өгөгдлийн санд тохирох хэмжээ биш. Өгөгдлийн сан ердийн үед хэр удаан асдаг болон нэг шалгалт хэр удаан үргэлжилдгийг харж утгуудаа сонгоно.
- `test` нь контейнер дотор ажиллах команд. Энд `pg_isready` амжилттай дууссан эсэх нь эрүүл төлөвт шилжих үндэс болно.
- `interval: 5s` нь шалгалт хоорондын хугацааг заана. Богиносговол бэлэн болсныг хурдан илрүүлэх боломжтой ч шалгалт илүү олон удаа ажиллана.
- `timeout: 3s` нь нэг шалгалтын дээд хугацаа. Жишээний `pg_isready -t 2` нь команд өөрөө хариу хүлээх хугацааг үүнээс богино тогтооно.
- `retries: 5` нь дараалсан бүтэлгүй шалгалтаар `unhealthy` төлөвт шилжих босго. Тоог өсгөх нь буруу командыг засахгүй, алдаатай төлөвийг илрүүлэхийг л хойшлуулна.
- `start_period: 20s` нь эхлэх үеийн бүтэлгүй шалгалтуудыг уг босгод тооцохгүй байх хугацаа. Энэ хугацаа дуусахыг заавал хүлээхгүй: шалгалт эрт амжилттай болбол үйлчилгээ `healthy` болно.
Эдгээр утгыг нэмээд аппын хүлээх хугацааны яг таг дээд хязгаар гэж үзэж болохгүй. Шалгалт хэзээ ажиллах, тус бүр хэр удаан үргэлжлэх, эхлэх хугацаанд амжилттай болох эсэхээс үр дүн хамаарна. `db` удаан хугацаанд `starting` байвал зөвхөн `retries`-г нэмэхийн оронд шалгалтын командыг өөрийг нь шалгах нь оношлогоонд илүү тустай.
Апп эхлэхгүй бол юуг шалгах вэ?

Эхлээд `docker compose config` ажиллуулж, эцсийн тохиргоонд `db`-гийн `healthcheck` болон аппын `condition: service_healthy` байгаа эсэхийг хар. Дараа нь `docker compose up -d --build` ажиллуулаад `docker compose ps -a` командаар хоёр үйлчилгээний төлөвийг үз. `db` удаан `starting` хэвээр байх эсвэл `unhealthy` болох үед аппыг хүлээлгэж буй шалтгаан нь шалгалтын талд байна.
`docker compose logs db` командаар PostgreSQL эхлэх үеийн алдааг харж болно. Шалгалтын үйлдлийг гараар давтах бол `docker compose exec db pg_isready -h 127.0.0.1 -U app -d app -t 2` ажиллуул. Контейнерийн хадгалсан шалгалтын үр дүн хэрэгтэй бол `docker inspect --format '{{json .State.Health}}' $(docker compose ps -q db)` командыг ашигла.
Гараар ажиллуулсан `pg_isready` амжилттай мөртөө healthcheck бүтэлгүй байвал Compose файл дахь команд, хувьсагчийн нэр, давхар долларын тэмдэг болон хашилтыг харьцуул. Харин `db` эрүүл болсон ч апп холбогдож чадахгүй байвал аппын хэрэглэж буй `DB_HOST`, хэрэглэгч, нууц үг, өгөгдлийн сангийн нэрийг шалга. Серверийн холболт хүлээн авах төлөв болон аппын жинхэнэ нэвтрэлт тусдаа шалгалт гэдгийг энэ ялгаа харуулна.
Өгөгдлийн сан дараа нь дахин асвал
`service_healthy` нь аппыг анх эхлүүлэх мөчид хамаарлыг хүлээлгэнэ. Өгөгдлийн сан ажиллаж байх явцад түр тасрах эсвэл өөрөө дахин асахад аппын аль хэдийн үүсгэсэн холболтыг энэ нөхцөл сэргээхгүй. Ийм үед апп холболтын алдааг таньж, тохирох хугацааны дараа дахин холбогдох чадвартай байх шаардлагатай.
Хэрэв Compose командаар `db`-г зориуд дахин эхлүүлэхэд аппыг дагаж дахин эхлүүлэх хэрэгтэй бол аппын `depends_on.db` хэсэгт `restart: true` нэмж болно. Энэ нь Compose-оор хийсэн дахин эхлүүлэх үйлдэлд хамаарна; өгөгдлийн сангийн контейнер өөрөө автоматаар дахин асах бүх тохиолдлыг орлохгүй. Тиймээс эхлэх дарааллыг healthcheck-ээр удирдахын зэрэгцээ ажиллаж буй аппын холболтын тасалдлыг аппын логикоор зохицуулна.
Мөн уншаарай:
Холбоотой нийтлэлүүд


Dockerfile-д ENV-ээр secret бүү хий: image дотор мөр нь үлдэнэ

n8n-ийг өөрийн серверт байрлуулах нь: нэг encryption key бүх нууцыг аварна

Docker Scout эсвэл Trivy: CVE тоо зөрөхөд аль тайланд итгэх вэ

AWS secret эргүүлэхдээ connection бүү тасал: хоёр хэрэглэгч ээлжлүүл

Pluto Security $42 сая босгов: AI эрсдэлийн 60% нь кодлогчдоос биш
Мэдээллийн товхимолд бүртгүүлэх
Web3, AI болон криптоны шинэ мэдээг шууд имэйл хайрцагтаа аваарай.