Невозможно использовать ARG в многоэтапной сборке докеров

Я пытаюсь использовать ARGS в многоэтапном процессе сборки докера.

Мой Dockerfile выглядит так:

ARG DOCKER_REGISTRY=example.com/docker
FROM $DOCKER_REGISTRY/openjdk8:latest AS installer 
ARG APP_VERSION=6.3.0.78 
ARG DOCKER_REGISTRY 
ARG REPO_TYPE=snapshot 
ARG DB_VERSION=12.2.0.11-ee
ARG DB_TYPE=oracle ARG PASSWORD

ARG DOCKER_REGISTRY 
ARG DB_VERSION 
ARG DB_TYPE
FROM ${DOCKER_REGISTRY}/${DB_TYPE}/database:${DB_VERSION} 
ARG DB_VERSION 
ARG DB_TYPE
ARG PASSWORD
RUN mkdir -p /opt/oracle/script
COPY --from=installer /opt/installer/target_script/* /opt/oracle/scripts/

Всякий раз, когда он получает второй шаг FROM в файле докера, он завершается с ошибкой invalid reference format, поскольку он не распознает синтаксис для получения изображения.

Я предполагаю, что он не знает, как обрабатывать ARG в многоэтапной сборке докера.


person Mickey Hovel    schedule 16.04.2020    source источник
comment
Вы должны обновлять ARG на каждом этапе.   -  person Maroun    schedule 16.04.2020
comment
разве это не то, что я делаю? можешь посмотреть? проблема со вторым ОТ. Я пытаюсь дважды вызвать тот же ARG, что и на первом этапе.   -  person Mickey Hovel    schedule 16.04.2020
comment
У вас есть DOCKER_REGISTRY в качестве глобального. Почему ты снова звонишь?   -  person Maroun    schedule 16.04.2020
comment
Я не знал об использовании области действия глобальной переменной в многоэтапном докере. и нашел несколько ответов в Интернете, чтобы снова позвонить в ARG. Как упоминалось здесь выше также   -  person Mickey Hovel    schedule 16.04.2020


Ответы (1)


ARG ограничены областью действия. Перед первой строкой FROM они являются глобальными и доступны только в строках FROM. На каждом этапе они ограничиваются до конца этого этапа. Итак, вам нужно:

ARG DOCKER_REGISTRY=example.com/docker
# move the DB_VERSION and DB_TYPE above the first FROM line
ARG DB_VERSION 
ARG DB_TYPE
FROM $DOCKER_REGISTRY/openjdk8:latest AS installer 

# none of these args seem to do anything, unless you have
# ONBUILD steps that depend on them in your openjdk image
ARG APP_VERSION=6.3.0.78 
ARG DOCKER_REGISTRY 
ARG REPO_TYPE=snapshot 
ARG DB_VERSION=12.2.0.11-ee
ARG DB_TYPE=oracle ARG PASSWORD

FROM ${DOCKER_REGISTRY}/${DB_TYPE}/database:${DB_VERSION} 

# none of these args are used either
ARG DB_VERSION 
ARG DB_TYPE
ARG PASSWORD

RUN mkdir -p /opt/oracle/script
COPY --from=installer /opt/installer/target_script/* /opt/oracle/scripts/
person BMitch    schedule 16.04.2020
comment
Как бы вы использовали аргумент PASSWORD для перехода к команде RUN в этом случае? Поскольку пароль не является чем-то, что я хотел бы сохранить как env и не отображать в команде docker inspect. - person Mickey Hovel; 16.04.2020
comment
@MickeyHovel для чего нужен пароль во время сборки? Это не то, что вы хотите вводить в образ в большинстве ситуаций, вы должны вводить это во время выполнения, позволяя использовать образ в разных средах и избегая пароля, сохраненного в любых слоях/конфигурации изображения. Во время выполнения на одном узле в виде файла конфигурации, доступного только для чтения, в рое или k8s с секретами, а еще лучше с KMS или хранилищем Hashicorp. - person BMitch; 16.04.2020
comment
Вариант использования следующий: разработчик должен иметь возможность запустить БД с правильными схемами и миграцией. Чтобы иметь правильные схемы, нам нужно запустить несколько сценариев БД. Чтобы запустить скрипт БД, нам нужно подключить БД с помощью прохода имени пользователя. Один из вариантов — запускать скрипты БД при развертывании пода в качестве контейнера инициализации и так далее, но хотелось бы иметь быстро развертываемый контейнер БД. - person Mickey Hovel; 17.04.2020
comment
@MickeyHovel лучше всего использовать отдельный контейнер инициализации или сценарий точки входа для инициализации новой БД. Другой вариант — жестко закодировать пароль БД во время сборки, а затем сбросить его на введенный пароль во время выполнения. Однако это усложняет сборку, увеличивает размер образа и часто вызывает проблемы при использовании томов. - person BMitch; 17.04.2020
comment
согласился, что лучше всего иметь его с точкой входа или контейнером инициализации при работе в k8s. в то же время я еще раз упомяну о необходимости быстрого запуска БД (это среда, ориентированная на разработчиков, и множество скриптов для выполнения) - person Mickey Hovel; 17.04.2020