Откройте каталог после импорта

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

Введение

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

Сначала выполните Wait for the Archive Database либо освойте используемые там YAML, проверки работоспособности, проекты Compose, журналы и ограниченный перезапуск с новыми данными. SQL и программирование приложения не требуются. Работа подготавливает независимую базу, исходные данные и эталон; файлы предыдущей VM не нужны. Предоставленная исходная база уже имеет правильную проверку окончательного TCP-сервиса.

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

Открывайте только после успешного импорта

На этом шаге вы поставите открытие каталога в зависимость от завершённого импорта, докажете, что настоящая ошибка блокирует его, и восстановите работу с исходными данными.

Сравните готовность базы и готовность приложения

Начните в Reference Archive. Найдите Market morning, откройте обе совпадающие записи и скачайте разные расшифровки. Вернитесь через Back to collection и изучите Ferry voices. Your Archive недоступен, а Collection Notes уже может объяснять коллекцию, не читая импортированных строк.

Переключитесь в Workstation, начиная в /home/labex/project/archive-opening:

cd /home/labex/project/archive-opening
cat compose.yaml
docker compose -p archive ps -a
docker compose -p archive logs importer catalog

База становится здоровой, и импортёр завершает настоящую работу. Но каталог попытался прочитать таблицу слишком рано и завершился с ошибкой вроде relation "entries" does not exist. Готовность базы принимать подключения не означает наличия данных приложения. У сайта намеренно нет скрытых повторных попыток запуска, поэтому это требование должна выражать зависимость.

Это окружение использует те же четыре роли и связи портов, что и предыдущая пошаговая работа. У db уже есть проверка TCP, а importer ждёт service_healthy. Оставшаяся проблема — catalog.depends_on.importer.condition: service_started. Она разрешает запуск каталога сразу после начала процесса импорта, когда его явно заданная шестисекундная учебная задержка и настоящая транзакция ещё впереди.

Задайте условие для настоящего потребителя

Замените это условие на service_completed_successfully. Оно проверяет успешное завершение, а не просто окончание процесса: ненулевой код импорта должен блокировать каталог. Одноразовый импортёр Exited 0 работает правильно; его не нужно удерживать в Running или назначать бесконечный перезапуск. Оставьте welcome независимым, поскольку статическим заметкам коллекции не нужна импортированная таблица.

Полный буквальный here-document сохраняет все предоставленные настройки и существующую проверку базы. Как и в предыдущей работе, > заменяет только compose.yaml; маркер в кавычках сохраняет содержимое буквально:

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 Riverside 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 Riverside Archive"
    ports:
      - "8091:8080"
volumes:
  data:
    labels:
      labex.course: dk04
COMPOSE
docker compose -p archive config

Если разбор не удался, исправьте указанные отступы по показанному блоку до запуска сервисов. Сохраните предоставленные приложение, импортёр, CSV, аутентификацию и порты без изменений.

Докажите, что неудачный импорт не открывает каталог

compose.bad.yaml — предоставленное переопределение, направляющее импортёр к отдельному некорректному CSV. Его ID записи содержит текст там, где настоящая таблица PostgreSQL требует целое число. Импортёр использует настоящую транзакцию и передаёт ненулевой код базы, а не имитирует успех. Исходный корректный сценарий остаётся в целости.

Сначала изучите учебный том и подтвердите метки проекта и курса, как изучалось ранее:

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

Ожидайте com.docker.compose.project: archive и labex.course: dk04. Следующая команда намеренно удаляет только временные учебные данные этого проекта, чтобы проверка плохих данных не могла заимствовать ранее импортированную таблицу:

docker compose -p archive down --volumes

Два аргумента -f объединяют обычную конфигурацию и предоставленное переопределение именно в этом порядке. Следующий запуск намеренно должен завершиться ошибкой с собственным кодом 1, поскольку импортёр завершается с ненулевым кодом:

docker compose -f compose.yaml -f compose.bad.yaml -p archive up -d --pull never --no-build
docker compose -f compose.yaml -f compose.bad.yaml -p archive ps -a
docker compose -f compose.yaml -f compose.bad.yaml -p archive logs importer

Прочитайте ошибку некорректного целого числа. База может оставаться здоровой, импортёр — Exited с ненулевым кодом, а каталог должен быть Created, ни разу не запущенным. Приветственный сервис всё ещё работает. Каталог, который запускается, а затем падает, — другой результат: ему разрешили потреблять неудачный импорт.

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

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

Переключитесь в Workstation. Снова проверьте те же метки учебного тома перед очисткой:

docker volume inspect archive_data --format '{{json .Labels}}'
docker compose -f compose.yaml -f compose.bad.yaml -p archive down --volumes

Запустите без переопределения, чтобы вернуться к исходным корректным данным. Это новое хранилище должно импортировать с нуля:

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

Ожидайте базу Healthy, импортёр Exited 0 и обе веб-роли Running. При обычной ошибке отсутствующего пути или YAML вернитесь в указанный рабочий каталог, прочитайте compose config или журнал сервиса, исправьте редактируемую конфигурацию и повторите только ограниченный перезапуск этого курса. Не редактируйте исходные строки, не подавляйте ошибки и не сбрасывайте VM для сокрытия проблемы.

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

Готовый каталог сохраняет все четыре идентичности, включая две разные записи Market morning:

Импортированный каталог после успешного холодного запуска

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

Резюме

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