Дождитесь базы данных архива

DockerBeginner
Практиковаться сейчас

Введение

The Common Archive хранит четыре записи о районе в PostgreSQL. Эталонный сайт работает, но новый архив попытался импортировать каталог до того, как база смогла принимать подключения. Сделайте первый запуск надёжным, научившись отличать работающий контейнер от готовой к использованию базы.

Вы должны знать основы Docker, журналы контейнеров, опубликованные порты и пути терминала. Эта работа знакомит со связями YAML, небольшим файлом Compose, проверкой работоспособности базы и условиями зависимостей. Знания SQL, администрирования PostgreSQL и написания приложений не требуются. Полный образ базы, импортёр, сайт и данные предоставлены.

Используйте Workstation, Reference Archive, Your Archive и Collection Notes. Все материалы — синтетические учебные записи. Намеренные задержки базы и импорта делают состояния запуска видимыми; они не описывают длительность в производственной среде. Выделите около 45 минут с учётом чтения и обычных ошибок; это оценка автора.

Дождитесь готовой к использованию базы

На этом шаге вы исправите одну зависимость небольшого полноценного приложения. Выполните наблюдения перед заменой конфигурации.

Воспользуйтесь нормальным архивом

Начните в Reference Archive. Найдите Market morning с помощью Search the collection и Search. Две записи имеют одно название, но представляют разные истории. Откройте обе, изучите ID, годы и категории и используйте Download transcript. Вернитесь через Back to collection, очистите поиск и изучите Ferry voices. Скачиваются настоящие тексты записей базы, а не маркеры завершения.

Переключитесь в Your Archive. Вкладка объясняет, что каталог не работает; она не заимствует эталон. Collection Notes уже работает, поскольку этот приветственный сервис не читает строки базы. Состояние контейнера Up не доказывает полноту каталога.

Прочитайте фактический неудачный запуск

Эталонная коллекция содержит четыре записи; обе записи Market morning имеют отдельные идентичности:

Полный эталонный каталог

Переключитесь в Workstation, которая открывается в /home/labex/project/archive-startup. При необходимости cd вернёт в эту папку. cat показывает файлы:

cd /home/labex/project/archive-startup
cat compose.yaml

Compose читает YAML. Отступы группируют свойства каждого сервиса; используйте пробелы, а не табуляцию. Четыре записи в services::

Сервис Реальная работа Успешное состояние
db PostgreSQL хранит записи Работает и принимает TCP-подключения
importer Одна транзакция импортирует предоставленный CSV Завершён с кодом 0
catalog Ищет и предоставляет записи и расшифровки Работает после успешного импорта
welcome Предоставляет Collection Notes без чтения базы Может работать до импорта

image выбирает подготовленный образ. entrypoint запускает предоставленную программу; вы её не редактируете. environment передаёт программе именованные настройки. PGHOST, PGUSER, PGPASSWORD и PGDATABASE сообщают клиентам, какую базу и учебную учётную запись использовать. Эти ограниченные рамками работы учётные данные предоставлены для этого задания. POSTGRES_* подготавливает эту учётную запись в новом хранилище. Не меняйте аутентификацию и не подменяйте базу.

Том data сохраняет файлы базы этого проекта. Относительный ./scenario подключает предоставленную входную папку к импортёру только для чтения, что обозначает :ro. База также читает свой предоставленный учебный скрипт задержки первого запуска. Опубликованный порт 8090:8080 связывает Your Archive с каталогом. Приветственная страница использует отдельный порт. Проект Compose группирует ресурсы; приведённый ниже -p archive всегда обращается к вашему учебному архиву, а эталон использует другой проект и том.

ps -a включает остановленные и ни разу не запущенные контейнеры. logs читает их настоящий вывод:

docker compose -p archive ps -a
docker compose -p archive logs db importer

В конце база сообщает о готовности, но импортёр уже не смог подключиться. Готовая позднее база не перезапускает неудачный импорт автоматически. Каталог остаётся незапущенным, поскольку его предоставленная зависимость уже ожидает успеха импортёра.

PostgreSQL кратковременно использует временный сервер инициализации до запуска окончательного TCP-слушателя. Проверка только локального Unix-сокета может дать готовность слишком рано для другого контейнера. pg_isready сообщает, принимает ли сервер подключения; она не доказывает правильность учётных данных или содержимого каталога.

Следующая проба только для чтения намеренно использует неправильный TCP-порт. exec запускает пробу в db, -T отключает выделение терминала, -h выбирает адрес, -p — порт, а -U/-d задают предоставленные пользователя и базу. На порту 6543 нет сервера, поэтому ожидайте no response и собственный код завершения 2:

docker compose -p archive exec -T db pg_isready -h 127.0.0.1 -p 6543 -U archivist -d archive

Это неудача пробы, а не потеря данных каталога. Окончательная база слушает обычный TCP-порт 5432. Проверка работоспособности должна обращаться именно к этому сервису.

Задайте готовность и запустите с новыми данными

Сохраните настройки приложения и предоставленные файлы без изменений. Добавьте настоящую healthcheck в db и измените условие базы у импортёра с service_started на service_healthy. test — команда, которую Docker выполняет внутри контейнера базы. Массив, похожий на JSON, использует CMD для прямого запуска указанной программы без оболочки. -h 127.0.0.1 выбирает окончательный TCP-слушатель; порт по умолчанию — 5432. interval: 1s, timeout: 2s и retries: 40 обеспечивают повторяемые ограниченные пробы, а не фиксированное ожидание, выдаваемое за готовность базы.

Условие каталога service_completed_successfully остаётся: успешный одноразовый импорт завершается с кодом 0 и не должен оставаться Running. Его ошибка должна блокировать каталог. Приветственная страница не зависит от импорта, поскольку ей не нужны импортированные данные.

Следующий буквальный here-document записывает полную конфигурацию, чтобы отступы воспроизводились. cat передаёт строки, > заменяет только compose.yaml, а маркер COMPOSE в кавычках предотвращает подстановки оболочки до закрывающей строки. Все остальные настройки приложения сохраняются:

cat > compose.yaml <<'COMPOSE'
services:
  db:
    image: dk04-postgres:16
    environment:
      POSTGRES_USER: archivist
      POSTGRES_PASSWORD: training-archive
      POSTGRES_DB: archive
      TRAINING_DB_DELAY: "8"
    volumes:
      - data:/var/lib/postgresql/data
      - ./scenario/slow-init.sh:/docker-entrypoint-initdb.d/10-training-delay.sh:ro
    healthcheck:
      test: ["CMD", "pg_isready", "-h", "127.0.0.1", "-U", "archivist", "-d", "archive"]
      interval: 1s
      timeout: 2s
      retries: 40
  importer:
    image: dk04-archive:1
    entrypoint: ["python3", "-B", "/app/importer.py"]
    environment:
      PGHOST: db
      PGUSER: archivist
      PGPASSWORD: training-archive
      PGDATABASE: archive
      TRAINING_IMPORT_DELAY: "6"
    volumes:
      - ./scenario:/scenario:ro
    depends_on:
      db:
        condition: service_healthy
  catalog:
    image: dk04-archive:1
    entrypoint: ["python3", "-B", "/app/archive.py", "catalog"]
    environment:
      PGHOST: db
      PGUSER: archivist
      PGPASSWORD: training-archive
      PGDATABASE: archive
      ARCHIVE_TITLE: "The Common Archive"
    ports:
      - "8090:8080"
    depends_on:
      importer:
        condition: service_completed_successfully
  welcome:
    image: dk04-archive:1
    entrypoint: ["python3", "-B", "/app/archive.py", "notes"]
    environment:
      ARCHIVE_TITLE: "The Common Archive"
    ports:
      - "8091:8080"
volumes:
  data:
    labels:
      labex.course: dk04
COMPOSE

Разберите конфигурацию до изменения ресурсов среды выполнения:

docker compose -p archive config

Если YAML не разбирается, прочитайте указанную строку, восстановите показанный блок с пробелами и повторите разбор. Не перезапускайте многократно некорректный файл.

Теперь проверьте первый запуск с пустым учебным хранилищем данных. Это намеренно удаляет только вашу временную учебную базу, а не исходный CSV или эталонный архив. Сначала изучите реальные метки тома:

docker volume inspect archive_data --format '{{json .Labels}}'

Убедитесь, что com.docker.compose.project — archive, а labex.course — dk04. Если любое значение отличается, остановитесь и изучите проект вместо удаления другого ресурса. down --volumes удаляет только контейнеры, сеть и объявленный том данных этого именованного проекта Compose:

docker compose -p archive down --volumes

up -d запускает сервисы в фоне. --pull never использует подготовленные образы; --no-build предотвращает их замену новыми сборками:

docker compose -p archive up -d --pull never --no-build
docker compose -p archive ps -a
docker compose -p archive logs importer

Ожидайте здоровую базу, импортёр Exited 0 и работающие каталог и приветственную страницу. Предоставленные задержки первого запуска и импорта предназначены явно для обучения. Никакой фиксированный sleep в файле Compose не заменяет реальную готовность или успешный импорт. Если предыдущая попытка оставила контейнеры с ошибками, изучите их журналы, исправьте конфигурацию, проверьте учебные метки тома и повторите этот ограниченный запуск с новыми данными.

Воспользуйтесь готовым каталогом

Переключитесь в Your Archive и обновите страницу. Найдите Market morning: должны появиться две записи с разными ID, годами, категориями и историями. Откройте каждую и используйте Download transcript, возвращаясь через Back to collection. Найдите Ferry, откройте Ferry voices и скачайте расшифровку. Очистите поиск для отображения всех четырёх записей. Также изучите The shared garden и его скачивание. Неизвестный URL записи должен показывать Record not found, что отличается от ошибки подключения или недоступного каталога.

Переключитесь в Collection Notes: независимая приветственная страница должна оставаться доступной. Reference Archive по-прежнему должен предоставлять исходную полную коллекцию. Оставьте свой итоговый архив работающим. Проверки сначала наблюдают за действующей базой, завершённым импортом и полными рабочими результатами. Затем они выполняют ваши неизменённые настройки готовности и зависимостей в отдельных временных новых хранилищах с другими явно заданными учебными задержками и некорректным образцом импорта. Эти тестовые окружения никогда не инициализируют и не исправляют ваш действующий архив. Отдельный изолированный тест также выполняет вашу неизменённую команду проверки работоспособности без какого-либо сервера базы; она должна отклонить такую недоступную конечную точку.

Резюме

Вы отличили запуск контейнера базы от готовности окончательного TCP-сервиса, настроили настоящую проверку работоспособности и обязали импортёр ждать её успеха. Затем новое хранилище данных получило полный каталог до открытия его потребителя, а независимая страница заметок осталась доступной.