惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
A
Arctic Wolf
aimingoo的专栏
aimingoo的专栏
D
Docker
Project Zero
Project Zero
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Microsoft Azure Blog
Microsoft Azure Blog
Hacker News: Ask HN
Hacker News: Ask HN
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
Blog — PlanetScale
Blog — PlanetScale
C
CERT Recently Published Vulnerability Notes
Microsoft Security Blog
Microsoft Security Blog
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
C
CXSECURITY Database RSS Feed - CXSecurity.com
B
Blog RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
C
Check Point Blog
阮一峰的网络日志
阮一峰的网络日志
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
Cisco Talos Blog
Cisco Talos Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Scott Helme
Scott Helme
Vercel News
Vercel News
Jina AI
Jina AI
The Hacker News
The Hacker News
月光博客
月光博客
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
李成银的技术随笔
T
True Tiger Recordings
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Stack Overflow Blog
Stack Overflow Blog
Security Latest
Security Latest
MongoDB | Blog
MongoDB | Blog
C
Cisco Blogs
S
Security Archives - TechRepublic
美团技术团队
Recorded Future
Recorded Future
I
Intezer

Все публикации подряд на Хабре

«Пропал интернет — продажи встали»: популярные мифы и неудобные вопросы про облачные онлайн-кассы Как вредоносный код переписал мой Git-коммит и заразил десятки проектов и несколько рабочих машин Какие методы оценки персонала реально работают в 2026 году Худшее собеседование в моей жизни 14 лет Solar JSOC: кто стоит за защитой от киберугроз в крупнейшем коммерческом SOC страны Где в IT джуны получают больше всего и куда пойти учиться Биокомпьютер из живых нейронов: что на самом деле построила FinalSpark Знания без практики — мертвы | Разница между «декларативной» и «процедурной» памятью у LLM Поднимаем Llama 3 в облаке: Ollama и Open WebUI SAST прямо в IDE: как Veai ищет уязвимости в Java/Kotlin-проекте и помогает их исправлять Почему мы до сих пор пользуемся Markdown? Архитектура безопасности во frontend-приложениях: Server Actions и защита данных в эпоху Next.js Torque — ваши сверхспособности для отладки k8s Антипаттерны Zabbix в крупной инфраструктуре: каталог базовых граблей Мёд, крабы и чипы ИИ фото и нейросети для создания картинок в 2026: ТОП-6 моделей для генерации реалистичной фотосессии с ИИ Горячо-холодно: как определить температуру бизнеса с помощью тепловой карты BPMSoft «Насколько вы контролируете то, из чего состоит ваш продукт?». Как и зачем проводить Open Source Analysis Дезагрегированный инференс LLM в Kubernetes: префилл, декодирование и планирование подов Как стать Go-разработчиком с нуля? Бесплатная программа обучения Разработка эмулятора NES на отечественном микроконтроллере К1921ВГ1Т predict_proba выдаёт 0.9 — но это не вероятность 90% OneClickRelease, или как мы ставим релизы одной кнопкой Ускорение INSERT/COPY в логической репликации PostgreSQL Полиморфные ссылки в PostgreSQL: три попытки помочь оптимизатору Ransomware: математический аппарат на службе зла Блеск и нищета SMM hh.ru Пишем универсальную глитч-машину Как не похоронить бизнес на старте: анатомия корпоративных конфликтов при учреждении ООО Как стиль общения может создавать карьерный тупик в ИТ Ответы с «деврел‑супервизии», вопрос восьмой: как держать веру команды и ЛПР, когда метрики шатаются Новинка: Прикладные API для искусственного интеллекта и Data Science Миграция с ingress-nginx: выбор нового контроллера Как мы «взломали» MasterSCADA4D: выкинули стандартные блоки и заставили SCADA работать на SVG Ожидание: сделать ИИ-примерочную обоев за 2 дня. Реальность: пришлось добучать свою модель на SD Как мы тестируем в Профи.ру: почему у нас нет пирамиды, зато есть ромб и матрица Об Open-source — спасителе человечества и kernel-сообществе пророке его… ТОП-10 сайтов мебельных магазинов: лучшие UX-решения и приемы юзабилити QSEAL: новый подход в резервном копировании средствами СХД Книга: «Windows Server 2022. Полное руководство по администрированию» Нейросети для работы с Excel: Выбираем ИИ для создания таблиц и написания формул Совместимость Test IT и RedOS: опыт автоматизации сборки, тестирования и сертификации RAG-Anything: Как собрать по-настоящему мультимодальный RAG Как я готовился к Certified Kubernetes Security Specialist (CKS) в 2026 году Я держал кафе 16 лет и кормил полгорода. Потом пришли зумеры и всё посыпалось Есть ли жизнь на фазе: откуда берёт энергию умный выключатель без подключённой нейтрали Go Computer. История удивительного планшета из 1992 года с графическим интерфейсом Экономия GPU-часов в 2,5 раза, уход ИИ в бэкенд и новые стандарты агентских систем: ML-дайджест Что скрывается за AI-стратегией SAP, Oracle и Palantir: зачем корпоративному ИИ семантическое ядро Почему RAG — фундамент любой AI-трансформации Персонализация как баг Одна на 9 команд: как я внедряла квартальное планирование в трайбе, который сопротивлялся переменам После ИИ писать код руками ощущается уже не как норма Языковые модели без машинного обучения Обмен через интернет между мобильными приложениями ТСД и 1С От плановых ремонтов к предиктивному обслуживанию: дорожная карта для главного инженера Параллельный импорт техники закрыли или нет? Юридический разбор Резервное электрообеспечение для ЦОДов: патенты в мире и в России 256 зелёных тестов на нерабочем коде. Так выглядит «услужливый клерк» внутри нейросети Бизнес-аналитика для сети из 300 аптек: прогноз продаж и другие показатели Impact Analysis в дизайн-системе: как мы сделали CI осмысленнее, а review понятнее Топ-5 лучших нейросетей 2026 года: полный список на любой случай в SpeShu.AI Что делает сотрудников по-настоящему эффективными: процессы, знания или технологии Как за один вечер я написал сервис инвентаризации оргтехники для филиальной сети из 16 локаций Склад нанимает — и не может остановиться. Дефицит складских работников в 2026 году: причины и решения Шёл за утечкой памяти, нашёл утечку диска: SXSSFWorkbook без dispose() в Apache POI Штраф в размере 155 000 рублей получил владелец сайта по заявлению Роскомнадзора Индивидуальный план развития: от формальной процедуры к инструменту управления экспертизой команды Как понять, что вы не управляете финансами, а просто смотрите на цифры Водоросли и микропластик Масштабирование LLM: от одного чипа до ЦОДа. Глава 3. Траснформеры Бомба замедленного действия взорвалась: эпоха ИИ «бери сколько унесёшь» закончилась Стимпанк как часть жизни. История паровых двигателей и место, которое они занимали в мире в XIX-XX веках. Часть 2 288-ядерный Xeon 6+ и другие серверные CPU От OCR к смыслу: как мы научили модель понимать, кто кому отец, мать, жених и свидетель Насколько плох был Intel iAPX 432 — проверяем на практике Приручаем железо: внедряем DevOps в промышленной разработке Когда Reality не хватает: добавляем Hysteria2 + Salamander в iOS-мессенджер, и как всегда грабли по дороге (ч.2) Разработчики не экстрасенсы: как мы перестали приносить туман вместо ТЗ Дайджест C++: новости, полезные материалы и “свой язык” на десерт Ещё один репозиторий моделей для Archi 10 простых шагов, чтобы создать позиционирование для продукта Загадочная поэма древнего Китая, работающая как компьютер CLOUD Act, GDPR и ваш DNS: что на самом деле может ваш провайдер Ускоряем и оптимизируем numpy, pandas, scipy и sklearn Idempotency keys: 5 граблей, которые мы поймали на проде Gamedev. Парсинг данных из Google Sheets и Excel в json без привлечения программистов Nano Banana Google AI: как использовать Нано Банана для генерации и редактирования изображений Два игрока на весь российский рынок ИИ: что показал ЦИПР-2026 Менеджер ресурсов ЯНДЕКС 360 (YANDEX 360) промокоды июнь 2026: промокод Yandex 360 скидка 40% на годовые тарифы Open-Source инструмент для автоматического перевода книг Ищу ранних тестировщиков для Android-версии agent harnesses Не используйте LLM для текста Увеличиваем продажи без слез аналитика Оптимизация запросов к PostgreSQL: 5 неочевидных настроек для продакшена 45 лет тюрьмы за DROP TABLE и переход Карпатого в Anthropic Планирование движения для ровера на ходовой Ackerman'а Революция в изучении языков Java — быстрая. Ваш код может таким не быть
Healthchecks в Docker Compose для Laravel: как сделать так, чтобы сервисы запускались в правильном порядке
Prog-Time · 2026-05-27 · via Все публикации подряд на Хабре

Время на прочтение3 мин

Охват и читатели1.2K

Туториал

Recovery Mode

Если вы хоть раз поднимали Laravel-проект в Docker Compose, наверняка сталкивались с ситуацией: контейнер с приложением стартует раньше, чем база данных успевает принять соединения, и миграции падают с ошибкой SQLSTATE[08006] или Connection refused. Перезапустишь — всё работает. На локалке терпимо, но в продакшене — это в падающие деплои.

По умолчанию Docker считает контейнер «живым», если его процесс запущен. Но это не всегда означает, что сервис внутри готов к работе.

Решение — правильно настроенные healthcheck’и и условие depends_on с параметром condition: service_healthy. В этой статье разберём, как это сделать для типичного стека Laravel: PHP-FPM, PostgreSQL, Redis и Nginx.

Почему depends_on без healthcheck не работает

Многие думают, что depends_on: [db] заставит контейнер с приложением ждать, пока база данных будет готова. На самом деле Docker Compose ждёт только запуска контейнера — то есть момента, когда процесс внутри стартовал. Между «процесс запустился» и «база готова принимать запросы» может пройти 5–15 секунд, особенно при первой инициализации.

Чтобы Compose действительно ждал готовности сервиса, нужно:

  1. Определить healthcheck у зависимого сервиса (БД, Redis и т. д.).

  2. В сервисе-потребителе указать depends_on в расширенной форме с condition: service_healthy.

Healthcheck для PostgreSQL

В официальный образ Postgres встроена утилита pg_isready — она и есть самая надёжная проверка готовности:

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 10s

Важный момент — параметр start_period. Он задаёт «грейс-период»: в течение этого времени неуспешные проверки не считаются провалами. Для Postgres это критично, потому что при первом запуске инициализируется PGDATA, и pg_isready временно отвечает «not accepting connections».

Healthcheck для Redis

redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 5s

Команда redis-cli ping возвращает PONG, когда сервер готов. Если у вас включена авторизация, добавьте -a $REDIS_PASSWORD или используйте переменную окружения REDISCLI_AUTH, чтобы пароль не светился в docker ps.

Healthcheck для PHP-FPM

С PHP-FPM сложнее: в стандартный образ php:8.3-fpm-alpine не входит ни curl, ни wget. Самый универсальный способ — использовать встроенный в PHP-FPM статус-пинг. Включаем его в конфиге пула:

  app:
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000 | grep -q pong"]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 15s

Не забудьте установить fcgi в Dockerfile:

RUN apk add --no-cache fcgi

Healthcheck для Nginx

Для Nginx достаточно простой проверки через wget (он есть в alpine-образе):

  nginx:
    image: nginx:alpine
    depends_on:
      app:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 5s
    ports:
      - "8080:80"

В конфиге Nginx добавьте отдельный location, который не идёт в PHP:

location = /health {
    access_log off;
    add_header Content-Type text/plain;
    return 200 "ok";
}

Полезные флаги

docker compose up --wait — поднимает все сервисы и блокирует консоль до тех пор, пока они не станут healthy (или не упадут). Идеально подходит для CI.

docker compose ps покажет столбец STATUS с пометкой (healthy) или (unhealthy) — удобно для быстрой диагностики на сервере.

Подводные камни

  • Слишком короткий interval создаёт лишнюю нагрузку. 5–10 секунд — обычно достаточно.

  • retries × interval определяет максимальное время ожидания. Если БД восстанавливается из бэкапа 2 минуты, а вы поставили retries: 3 и interval: 5s — контейнер пометится как unhealthy раньше, чем база реально упадёт.

  • Healthcheck должен проверять реальную готовность, а не просто наличие процесса. Например, pgrep postgres вернёт успех ещё до того, как Postgres примет первое соединение.

  • Не злоупотребляйте condition: service_healthy в проде на одном узле: если зависимый сервис упадёт и перезапустится, потребитель не «переподпишется» автоматически. Эта механика работает только при старте.

Итог

Несколько строчек YAML экономят часы отладки и убирают целый класс «магических» проблем: миграции, которые иногда падают; тесты, которые иногда красные; деплои, которые иногда обрываются. Если у вас в проекте до сих пор стоит голый depends_on без условий — самое время это починить.

Больше Healthcheck конструкций для docker compose вы можете найти здесь.