Код-ревью Middle Docker Compose обновлено

Ревью: compose.yaml

Вопрос

Найди проблемы в compose-файле для продового сервера.

version: "3.8"
services:
  api:
    image: registry.example.com/api:latest
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:S3cretPass@db:5432/app
    depends_on:
      - db
  db:
    image: postgres:16
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: S3cretPass

Коротко

Исправленный вариант: ${DBPASSWORD:?} прервёт запуск, если переменная не задана в .env. Если API должен быть доступен только через reverse proxy на том же сервере, его порт тоже стоит привязать к 127.0.0.1.

Что должен найти ревьюер

  1. Стильстрока 1
    Поле version устарело: Compose v2 его игнорирует и выводит предупреждение. Удалить.
  2. Ошибкастрока 4
    Тег latest: на сервере неизвестно, какая версия, откат невозможен. Указать версию или digest.
  3. Безопасностьстрока 8
    Пароль в открытом виде в файле, который лежит в репозитории. Вынести в .env вне git (${DB_PASSWORD}) или secrets:.
  4. Ошибкастрока 10
    depends_on без условия: API может стартовать раньше, чем база готова. Нужен healthcheck у db и condition: service_healthy.
  5. Безопасностьстрока 14
    Порт базы опубликован на всех интерфейсах и обходит ufw. API ходит к базе по внутренней сети, публикация не нужна.
  6. Ошибкастрока 12
    У базы нет тома: данные пропадут при пересоздании контейнера. Нужен volumes: - pgdata:/var/lib/postgresql/data.
  7. Стиль
    Нет restart и ограничения логов: после ребута сервисы не поднимутся, json-логи растут без ограничений.

Разбор

Исправленный вариант:

services:
  api:
    image: registry.example.com/api:1.4.2
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:${DB_PASSWORD:?}@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    logging:
      options: { max-size: "10m", max-file: "3" }
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD:?}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      retries: 10
    restart: unless-stopped

volumes:
  pgdata:

${DB_PASSWORD:?} прервёт запуск, если переменная не задана в .env. Если API должен быть доступен только через reverse proxy на том же сервере, его порт тоже стоит привязать к 127.0.0.1.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.