Введение
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, остаётся незапущенным после настоящей ошибки импорта и открывает полный новый каталог после восстановления корректных входных данных. Независимая приветственная страница остаётся полезной на всём протяжении работы.



