Как определить, что контейнер Docker готов принимать подключения?

«Как определить, что контейнер Docker готов принимать подключения?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Готовность контейнера определяется через health checks и проверку доступности портов. В production-средах я полагаюсь на встроенные health check'и Docker.

1. Health Check в Dockerfile: Определяю HEALTHCHECK на этапе сборки образа. Docker будет самостоятельно отслеживать статус.

FROM nginx:alpine
# Проверяет, отвечает ли Nginx на HTTP-запрос
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 
  CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1

После запуска статус проверяется командой:

docker inspect --format='{{.State.Health.Status}}' <container_name>
# Возвращает "starting", "healthy" или "unhealthy"

2. Использование wait-for-it или dockerize в entrypoint: Для зависимостей между контейнерами (например, ожидание БД) использую скрипты.

# Использование wait-for-it.sh
COPY wait-for-it.sh /wait-for-it.sh
RUN chmod +x /wait-for-it.sh
CMD ["/wait-for-it.sh", "db:5432", "--", "python", "app.py"]

3. Проверка в оркестраторах (Docker Compose/Kubernetes): В docker-compose.yml задаю healthcheck и зависимость сервисов через depends_on.

services:
  app:
    build: .
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

4. Прямая проверка порта: Для простых случаев в скриптах использую nc (netcat) или проверку через /dev/tcp/ в bash.

# Проверка доступности порта 8080 в течение 60 секунд
timeout 60 bash -c 'until echo > /dev/tcp/localhost/8080; do sleep 2; done'

Ключевой принцип: готовность приложения (application readiness) — это не просто запущенный процесс, а подтверждение, что он может обслуживать запросы.