переменная среды docker compose не устанавливает переменную внутри Dockerfile

#php #docker #nginx #docker-compose #dockerfile

#php #docker #nginx #docker-compose #dockerfile

Вопрос:

Я создаю свое приложение для локальной разработки docker-compose.yaml , используя два Dockerfiles — один для приложения (WordPress), а другой для nginx. Поскольку это конкретное приложение, созданное с использованием конвейера Jenkins, я не могу изменить файлы Dockerfile, но я хотел бы иметь возможность тестировать локально ту же среду, что и на промежуточном и производственном серверах.

Часть php работает, но nginx терпит неудачу. Dockerfile Для nginx выглядит так:

 FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

COPY --from=DOCKER_IMAGE_NAME_PHP /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]
  

DOCKER_IMAGE_NAME_PHP Часть завершается с ошибкой

ОШИБКА: службе ‘nginx’ не удалось выполнить сборку: недопустимо из значения флага DOCKER_IMAGE_NAME_PHP: недопустимый формат ссылки: имя репозитория должно быть в нижнем регистре

В моей docker-compose.yaml части для nginx у меня есть

 nginx:
    build:
      context: .
      dockerfile: Dockerfile.static
    container_name: web-service
    working_dir: /var/www
    volumes:
      - .:/var/www
    environment:
      - "DOCKER_IMAGE_NAME_PHP=app-admin"
      - "DOCKER_IMAGE_NAME_NGINX=web-service"
    depends_on:
      - app
    ports:
      - 8090:80
  

Я думал, что установки environment в файле compose будет достаточно, и что это будет использоваться ( app-admin это container_name часть php с WordPress).

В моих сценариях конвейера Jenkins эти имена используются для создания приложения и статических изображений вручную (с помощью docker build -t DOCKER_IMAGE_NAME_PHP -f Dockerfile.php ), а затем для имен устанавливается значение env like

 echo -e "DOCKER_IMAGE_NAME_PHP=$DOCKER_IMAGE_NAME_PHP" >>env
  

Редактировать

Как и в предложенном ответе, я пробовал добавлять args под build ключом

 build:
  context: .
  dockerfile: Dockerfile.static
  args:
    - "DOCKER_IMAGE_NAME_PHP=app-admin"
  

Затем в моем Dockerfile я добавил

 FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

ARG DOCKER_IMAGE_NAME_PHP

COPY --from=$DOCKER_IMAGE_NAME_PHP /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]
  

Но я все равно получаю ошибку. Я пробовал ${DOCKER_IMAGE_NAME_PHP} , но это не помогает.

Странно то, что добавление RUN echo $DOCKER_IMAGE_NAME_PHP , когда я запускаю это, я вижу

 Step 6/8 : RUN echo $DOCKER_IMAGE_NAME_PHP
 ---> Running in 0801fcd5b77f
app-admin
  

Но она не распознается в COPY команде. Как же так?

РЕДАКТИРОВАТЬ 2

Получается, я не могу этого сделать:

https://github.com/moby/moby/issues/34482

Потому --from что ожидает имя изображения (которое я пытаюсь передать ему из службы предыдущей сборки, но в моем случае оно динамическое). Это работает в Jenkins, поскольку я выполняю docker build команду, а переменные доступны в скрипте bash…

Ответ №1:

COPY --from не поддерживает переменные, но FROM поддерживает.

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

 ARG DOCKER_IMAGE_NAME_PHP=php:7.3
FROM ${DOCKER_IMAGE_NAME_PHP} as php-image
FROM nginx:latest

COPY scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY ./config/nginx.conf /opt/nginx.conf
COPY ./config/nginx.conf.prd /opt/nginx.conf.prd

COPY --from=php-image /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]
  

почти аналогичный пример находится в документах

Комментарии:

1. Кажется, это правильно указывает имя изображения, я не думаю, что предыдущий этап был установлен, поэтому мне нужно будет изучить это немного подробнее. Спасибо!

2. ваш образ создается из последнего базового образа, указанного вами в многоступенчатом dockerfile, в данном случае — только из образа nginx. предыдущие этапы существуют только для того, чтобы вы могли COPY --from их использовать, как мы это делали. спасибо и удачи!

Ответ №2:

Для этого вы должны использовать ARG в Dockerfile .

https://docs.docker.com/engine/reference/builder/#arg

environment в docker-compose.yml недоступен при сборке.

https://docs.docker.com/compose/compose-file/#environment

Вы также можете использовать arg в docker-compose.yml:

https://docs.docker.com/compose/compose-file/#args

Комментарии:

1. Я добавил ее как args build ключ в файле compose, и я добавил ARG DOCKER_IMAGE_NAME_PHP after FROM в свой Dockerfile . Когда я это делаю RUN echo ${DOCKER_IMAGE_NAME_PHP} , я вижу желаемый результат app-admin , но я все равно получаю сообщение об ошибке, когда у меня есть COPY --from=${DOCKER_IMAGE_NAME_PHP} /var/www/html/ /var/www/html/ (пробовал также, но не {} получил того же результата). Есть какие-либо подсказки относительно того, что я делаю неправильно?

2. да, это известная проблема: github.com/docker/for-mac/issues/2155 и github.com/moby/moby/issues/34482