Перейти к содержанию

Передача образов через registry

Локальный image можно запустить на текущем Engine, но для передачи другому разработчику нужен понятный способ доставки. В этом уроке опишем публикацию API и веб-клиента через registry и зафиксируем договор выпуска. Результат — точные имена двух образов, реестр фактических сведений и понимание того, что не переносится вместе с image.

Registry хранит images; он не превращает их в работающий сайт автоматически. Токен, repository, сборки и доступ к сети создаёт читатель в своём окружении. При написании серии автор не выполнял login, push, pull или размещение. Команды ниже являются ожидаемым сценарием самостоятельного повторения, а не сообщением о состоявшейся публикации.

Подготовим передаваемые материалы

Для API нужен обычный Dockerfile, а для клиента — multi-stage Dockerfile из предыдущего урока. У frontend должен существовать настоящий package-lock.json, полученный читателем. Dev-image с watcher и подключением исходников не выбираем в качестве релиза статического клиента: его роль связана с рабочей папкой и инструментами разработки.

После собственной успешной сборки compose.prod.yaml локальные образы имеют имена professorweb-container-lab-api:release-01 и professorweb-container-lab-web:release-01. Сначала прочитайте их список и подтвердите, что они относятся к текущим исходникам. Если build не завершился, наличие старого такого же тега не доказывает наличие новой версии. Подготовка выпуска должна связывать исходное состояние и конкретное содержимое image.

Манифест, lockfile и digest базовых images относятся к воспроизводимости. Пока выбраны изменяемые node:24-bookworm-slim и nginx:stable-alpine, повторная сборка позднее может получить обновлённую основу. Это не повод отказаться от обновлений, но их нужно различать с намеренным изменением собственного кода. Не записываем придуманный digest ради красивого реестра.

Выберем namespace и repository

В публичном registry имя обычно включает namespace владельца и repository. Для двух сервисов полезно использовать разные repositories: catalog-api и catalog-web могут обновляться вместе по договору релиза, но остаются разными images. Пользователь registry должен иметь право записи в выбранное место; совпадение текста namespace с чьим-то аккаунтом не даёт такого права.

В командах ниже замените YOUR_NAMESPACE собственным действительным namespace. Переменная содержит имя, а не пароль. Не публикуйте значение токена в статье, исходниках или shell-истории как часть команды. Для Docker Hub можно выполнить login с явно выбранным именем и ввести подходящий токен по запросу. Поддерживаемые способы и хранение учётных данных описаны в официальном справочнике docker login.

PW_DOCKER_NAMESPACE='YOUR_NAMESPACE'
docker login --username "$PW_DOCKER_NAMESPACE"
docker image tag professorweb-container-lab-api:release-01 "$PW_DOCKER_NAMESPACE/professorweb-catalog-api:release-01"
docker image tag professorweb-container-lab-web:release-01 "$PW_DOCKER_NAMESPACE/professorweb-catalog-web:release-01"

Tag даёт существующему image подходящее имя для registry. Он не собирает новый клиент и не меняет файлы API. Если namespace, image или версия перепутаны, исправлять нужно эти сведения до push. Успешный login также не доказывает право записи в произвольный repository; авторизация и адрес назначения являются разными условиями.

Сведение Что фиксирует Где получить действительное значение
Namespace/repository Адрес передаваемого image Из собственного выбранного registry
Релизный tag Человеческое имя версии Из принятой политики проекта
Digest Конкретное содержимое Из фактической публикации или полученного image
Platform Совместимую архитектуру Из результата своей сборки и inspect
Backup каталога Отдельные пользовательские данные Из отдельной процедуры хранения

Выполним отдельную операцию push

Когда читатель намеренно готов опубликовать выбранные материалы, выполняются две отдельные операции. Их последствия зависят от доступности repository, его публичности и правил registry.

docker image push "$PW_DOCKER_NAMESPACE/professorweb-catalog-api:release-01"
docker image push "$PW_DOCKER_NAMESPACE/professorweb-catalog-web:release-01"

Ожидается загрузка нужных слоёв и фактическая ссылка на результат. Возможность повторного использования уже существующих слоёв не является гарантированным временем передачи. Не переносим цифры из другого проекта в прогноз нашего. Правила команды, включая выбор тегов, приведены в справочнике image push.

Перед публикацией нужно знать состав image. .dockerignore помог ограничить входы, но он не проверяет самостоятельно смысл каждого файла. Подготовленные JSON-данные содержат только публичные учебные записи. Настоящие секреты, приватная база и сохранённые документы не должны оказаться в публичном image под видом удобной начальной конфигурации.

Проверим передачу без удаления всего окружения

После самостоятельной публикации другой Engine с подходящей платформой может получить images через pull. Не требуется предварительно удалять все локальные контейнеры и volumes, чтобы доказать возможность передачи. Достаточно отдельного понятного окружения или чтения фактических references и результата получения.

docker image pull "$PW_DOCKER_NAMESPACE/professorweb-catalog-api:release-01"
docker image inspect "$PW_DOCKER_NAMESPACE/professorweb-catalog-api:release-01" --format '{{json .RepoDigests}}'

Содержимое RepoDigests читатель записывает только из своего результата. Тег release-01 при разрешённой перезаписи repository может позднее указать на другой image. Digest помогает назвать конкретное содержимое, однако не доказывает сам по себе безопасность программы или успешность HTTP-сценариев. Для релизов нужна понятная политика обновления тегов, проверки и происхождение сборки.

Процессорная архитектура также не исчезает. Image, собранный на ARM-компьютере, не следует без проверки обещать совместимым с любым сервером x86. Базовый официальный image может иметь несколько платформ, но собственная сборка и её manifest требуют отдельного решения. Возможность buildx и multi-platform выпуска можно изучать дальше; в этом курсе такой выпуск не выполнялся и не объявляется готовым.

Заполним реестр только наблюдениями

В корне проекта добавьте release-record.json. Это полный начальный редакционный файл. Null означает отсутствующее наблюдение, а не пустую успешно завершённую публикацию.

{
  "execution": "not_run",
  "api": {
    "tag": null,
    "digest": null,
    "platform": null
  },
  "frontend": {
    "tag": null,
    "digest": null,
    "platform": null
  },
  "catalog_backup": null,
  "reader_created_lockfile": null,
  "registry_publication": "not_run",
  "real_deployment": "not_run"
}

После собственных действий читатель связывает actual tag, digest и platform с сохранённым исходником и lockfile. Отдельно отмечает получение клиента и API, их ожидаемые ответы и состояние данных. Один общий флаг «готово» скрывает слишком много разных условий: можно загрузить API и забыть frontend, либо получить оба image без volume с нужным каталогом.

Что нужно переносить отдельно

Изменённый catalog.json в named volume не входит автоматически в pushed image. Image содержит исходный fixture, а volume хранит текущее runtime-содержимое. Если второй разработчик запускает новый пустой volume, он получает начальные записи. Для действительных пользовательских данных требуется отдельная резервная копия, передача и проверка восстановления; registry такую процедуру не заменяет.

Environment, публикация портов, домен, HTTPS и права доступа также являются настройками размещения. Compose-файл помогает описать часть из них, но локальное имя проекта и loopback-порт не становятся внешним адресом сайта сами по себе. Для настоящего хоста понадобятся его условия и отдельный план выпуска с возможностью вернуться к прежнему состоянию.

Архив серии содержит только наши исходники, редакционные реестры и полные snapshots, без registry-токенов, настоящих образов и сохранённых volumes. Execution остаётся not_run. К концу курса можно объяснить каждую границу проекта: образ, экземпляр, context, публикацию порта, dev-mount, постоянные данные, статическую сборку и registry. Следующий самостоятельный шаг — подтвердить эти ожидаемые сценарии в выбранном окружении и лишь затем готовить настоящее размещение.

Оглавление серии