Использование многоэтапных сборок Docker

У меня есть два контейнера для двух отдельных сайтов и один контейнер для nginx. Все, что я хочу сделать, это скопировать файлы сборки каждого сайта в /usr/share/nginx/html/<site_name>/ в контейнере nginx. Я хочу сохранить отдельные Dockerfile для каждого сайта и назвать контейнеры сайтов builder_one и builder_two, чтобы копировать файлы из них в nginx Dockerfile:

FROM nginx:latest
COPY ./conf.d/ /etc/nginx/conf.d/
RUN mkdir /usr/share/nginx/html/site_one
RUN mkdir /usr/share/nginx/html/site_two
COPY --from=builder_one /usr/src/site_one/build/ /usr/share/nginx/html/site_one/
COPY --from=builder_two /usr/src/site_two/build/ /usr/share/nginx/html/site_two/

Как бы то ни было, я получаю сообщение об ошибке:

------
 > [dockernginx-nginx] FROM docker.io/library/builder_two:latest:
------
failed to solve: failed to load cache key: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

Ошибка при запуске команды COPY, поскольку она пытается извлечь контейнер из реестра Docker. Почему? Как правильно копировать файлы в контейнер nginx?


Может быть, есть другой способ добиться этого?

COPY --from принимает имя изображения (или псевдоним из текущего Dockerfile). Как вы создали два изображения с содержимым; они на самом деле называются builder_one и builder_two?
David Maze 12.04.2023 15:44

@DavidMaze Я использовал псевдоним, например FROM node:latest AS builder_one. Ожидал, что он будет работать с файлами докеров. Обращение к ним по имени контейнера сработало. Спасибо.

Karolis 12.04.2023 15:51

Этот синтаксис работает только в пределах одного Dockerfile. Вам придется использовать имя docker build -t image-name:tag в другом Dockerfile.

David Maze 12.04.2023 15:52
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
0
3
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно объявить имена образов из ваших предыдущих сборок в том же файле докера.

В вашем примере:

FROM <builder_one_image_name> as builder_one
FROM <builder_two_image_name> as builder_two

FROM nginx:latest
COPY ./conf.d/ /etc/nginx/conf.d/
RUN mkdir /usr/share/nginx/html/site_one
RUN mkdir /usr/share/nginx/html/site_two
COPY --from=builder_one /usr/src/site_one/build/ /usr/share/nginx/html/site_one/
COPY --from=builder_two /usr/src/site_two/build/ /usr/share/nginx/html/site_two/
Ответ принят как подходящий

Вы уточняете в комментариях, что у вас есть три отдельных Dockerfile, и начинаете первые два с синтаксисом FROM base-image AS builder_one. Этот синтаксис псевдонима работает только в пределах одного Dockerfile; псевдонимы не сохраняются как часть образа, и на них нельзя ссылаться из других файлов Dockerfile.

COPY --from также может принимать полное имя изображения. Для конкретной настройки, которую вы описываете, вам необходимо создать каждый из образов компонентов с известным тегом.

docker build -t myname/builder-one ./site_one
docker build -t myname/builder-two ./site_two

а затем в финальном файле Dockerfile используйте эти имена изображений

FROM nginx:latest
COPY ./conf.d/ /etc/nginx/conf.d/
COPY --from=myname/builder-one /usr/src/site_one/build/ /usr/share/nginx/html/site_one/
COPY --from=myname/builder-two /usr/src/site_two/build/ /usr/share/nginx/html/site_two/

Образы компонентов не нуждаются в синтаксисе FROM ... AS, и обычно вы можете удалить часть AS alias из строки FROM финальной стадии Dockerfile.

Я хочу запустить все через единую docker compose конфигурацию. Возможно ли это без создания изображений сайта отдельно? Я пытался использовать конфигурацию службы depends_on для nginx, где я перечисляю оба сайта, но это не помогает, и мне все равно нужно сначала создавать изображения сайтов отдельно.

Karolis 12.04.2023 21:22

Compose не может сказать, что одна сборка образа зависит от другой. Есть такие варианты использования, когда вы можете себе представить, что хотите этого; другой пример — попытка создать базовый образ с помощью общих библиотек и инструментов, а затем расширить его в других службах. Для этой конкретной настройки один многоэтапный Dockerfile, вероятно, обеспечит наиболее плавный опыт Compose.

David Maze 12.04.2023 21:28

«У Compose нет возможности сказать, что одна сборка образа зависит от другой». Но разве это не то, что делает depend_on? При этом сначала создаются образы зависимостей, а затем зависимый, просто я не могу ссылаться на них по имени в окончательном файле Dockerfile. В любом случае, я, вероятно, выберу один файл Dockerfile или даже создам отдельные образы, что не является большой проблемой.

Karolis 12.04.2023 21:39

Нет, depends_on: говорит, что один контейнер не может запускаться раньше другого контейнера. Вы не можете ограничить порядок build:.

David Maze 13.04.2023 00:47

Другие вопросы по теме