РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
⊗dcPhMyWt 30 of 30 menu
◀

Ожидание базы в Docker

Ожидание базы пускает сайт только после того, как сервер ответил на проверку, а не сразу после старта процесса. Контейнер MySQL может уже работать, но ещё не принимать клиентов - страница с PDO в этот момент падает или отдаёт пустой ответ.

Простой depends_on лишь задаёт порядок: PHP стартует после запуска процесса db, но готовность не ждёт. Условие service_healthy откладывает app, пока проверка здоровья не отметит успех. Сервис db получает healthcheck с mysqladmin ping и паузой 5 секунд. Образ PHP и связка с nginx те же, что при запросе PDO. Шаблон Dockerfile:

FROM php:8.5-fpm RUN docker-php-ext-install pdo_mysql

Файл compose.yaml с проверкой здоровья:

services: web: image: nginx ports: - "8080:80" volumes: - ./site:/var/www/html - ./default.conf:/etc/nginx/conf.d/default.conf app: build: . environment: DB_HOST: db DB_NAME: app DB_USER: app DB_PASSWORD: demo volumes: - ./site:/var/www/html depends_on: db: condition: service_healthy db: image: mysql:9.7 environment: MYSQL_ROOT_PASSWORD: demo MYSQL_DATABASE: app MYSQL_USER: app MYSQL_PASSWORD: demo healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 5s retries: 10

Конфиг nginx на порту 8080 с общей папкой сайта:

server { listen 80; root /var/www/html; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass app:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }

Сценарий читает поле body через PDO:

<?php $dsn = 'mysql:host=' . getenv('DB_HOST') . ';dbname=' . getenv('DB_NAME'); $pdo = new PDO($dsn, getenv('DB_USER'), getenv('DB_PASSWORD')); $row = $pdo->query('SELECT body FROM notes LIMIT 1')->fetch(PDO::FETCH_ASSOC); echo $row['body'];

Таблицу notes со словом hello создают командой клиента после подъёма. Подъём проекта:

docker compose up -d --build docker compose exec db mysql -uapp -pdemo app -e "CREATE TABLE IF NOT EXISTS notes (id INT PRIMARY KEY AUTO_INCREMENT, body VARCHAR(255)); INSERT INTO notes (body) VALUES ('hello');"

Первое открытие localhost:8080 чаще сразу показывает hello, потому что FPM не стартовал раньше успешной проверки db. Список сервисов покажет здоровье базы перед тем, как app перейдёт в работу.

Добавьте проверку готовности сервису db с паузой 3 секунды и свяжите php с условием здоровья, а не только с порядком запуска.

Поднимите проект в фоне и отметьте в списке сервисов, что PHP стартовал после успешной проверки базы.

←
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить