Compose: Переменные среды не применяются при сборке контейнера

Созданный на 10 авг. 2015  ·  16Комментарии  ·  Источник: docker/compose

При сборке контейнера переменные среды не применяются.

docker-compose.yml:

img:
    build: img
    environment:
        VAR: Hello

/ img / Dockerfile:

FROM python:2.7
RUN python -c 'import os; print os.environ["VAR"]'

Ожидается, что будет написано «Hello», получено KeyError: VAR - отсутствует переменная среды.

Если вы войдете в контейнер с помощью docker-compose run --rm img bash (после удаления последней сбойной строки) и выполните python -c 'import os; print os.environ["VAR"]' вы получите ожидаемый результат.

docker-compose==1.3.3

docker-version :

Client version: 1.7.1
Client API version: 1.19
Go version (client): go1.4.2
Git commit (client): 786b29d
OS/Arch (client): linux/amd64
Server version: 1.7.1
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 786b29d
OS/Arch (server): linux/amd64
kinquestion

Самый полезный комментарий

ответ на этот вопрос о переполнении стека помог https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

можно сопоставить переменные среды .env с ARGS, которые будут использоваться Dockerfile во время сборки.

docker-compose.yml

version: "2"
services:

  lumen:
    build:
      context: .
      dockerfile: ./Dockerfile
      args:
        - PORT=${PORT}
    volumes:
       ...

Dockerfile

FROM php:7.0-apache
ARG PORT

ENV PORT "$PORT"

EXPOSE ${PORT}
...

Все 16 Комментарий

Это ожидаемо. Ключ environment: в docker-compose.yml совпадает с указанием его в команде docker run для запуска контейнера. build и dockerfile - старые ключи, используемые для построения изображения.

Возможно, это не очевидно из документации и может быть улучшено.

Docker не поддерживает внедрение среды в среду сборки (она должна быть частью Dockerfile), но я считаю, что есть несколько открытых предложений по добавлению поддержки для чего-то подобного.

Просто справочник для тех, кто обнаружит эту проблему, вот обсуждение докеров относительно переменных времени сборки: https://github.com/docker/docker/issues/14634 и соответствующий PR: https://github.com/docker/docker / pull / 15182

Это нас сильно укусило, действительно нужны лучшие документы.

Документация действительно сбивает с толку, например, говорится о env-файле, который используется для docker-compose.yml и используется для docker run . Учитывая, что docker-compose - это инструмент оркестровки для создания и запуска контейнеров, легко предположить, что среда будет применяться ко времени сборки, используя --env <key>=<value> или что-то в этом роде.

Укусила меня тоже.
Просто чтобы оставить примечание, что переменные среды могут быть установлены как аргументы сборки в файле создания. Как и другие участники этого потока, я изначально ожидал, что env_file или среда будут использоваться как при сборке, так и при запуске.
Проверено с помощью файла compose v2, docker-compose v1.7, docker-engine v1.11.

Обновленные документы в https://github.com/docker/compose/pull/3747

Обратите внимание, что если вам нужно включить переменные env из файла, вы можете сделать следующее. Для этого потребуется (в разделе сборки docker-compose) аргументы, установленные из этих переменных, на которые вы затем можете ссылаться в своем файле docker. Это означает, что, хотя вы не можете напрямую повторно использовать свой env_file, вы можете сделать это с небольшой дополнительной работой.

env $(cat vars.env | xargs) docker-compose up --build <whatever>

ответ на этот вопрос о переполнении стека помог https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

можно сопоставить переменные среды .env с ARGS, которые будут использоваться Dockerfile во время сборки.

docker-compose.yml

version: "2"
services:

  lumen:
    build:
      context: .
      dockerfile: ./Dockerfile
      args:
        - PORT=${PORT}
    volumes:
       ...

Dockerfile

FROM php:7.0-apache
ARG PORT

ENV PORT "$PORT"

EXPOSE ${PORT}
...

@williamli Можете ли вы добавить ссылку на вопрос о переполнении стека?

Извините, ребята, я не уверен, что понимаю, как решить эту проблему, и я хотел бы использовать предварительно созданный образ.

Например, мой составной файл:

версия: '3'

Сервисы:
web1:
изображение: Softwaremaker / web-w
окружающая обстановка:

  • wtmsdemo_customerapi01 = http: // api1 / api / значения
    порты:
  • «89:80»
    зависит от:
  • api1
    api:
    изображение: softwaremaker / api-w
    сети:
    по умолчанию:
    внешний:

имя: нат

Раньше я думал, что образ api (softwaremaker / api-w) сможет разрешить переменные среды, которые я установил выше, но это не работает.

@PatrLind
добавлена ​​ссылка на stackoverflow в мой исходный комментарий.

https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile

Проблема по-прежнему актуальна для файлов env, кроме файлов по умолчанию .env .
Fe Следующий код не будет работать:

  nginx:
    env_file:
      - .env
      - .env.local
    environment:
     - SERVER_NAME=${SERVER_NAME}
    build:
      context: ./nginx
      dockerfile: Dockerfile
      args:
        server_name: ${SERVER_NAME}

в то время как SERVER_NAME определен во втором файле env ( .env.local ).
Я не вижу вариантов передачи переменных env из .env.local для создания контекста ((

@remort
Я также могу подтвердить это, если у меня есть переменные, используемые во время сборки, они передаются в процесс сборки только в том случае, если файл называется .env если они называются .env.docker они не получают подобрал. Даже если env_file указано для использования файла .env.docker .

Мое решение для этого во время моей сборки копирует другой именованный файл env и переименовывает его в .env

COPY .env.docker ${APP_HOME}/.env
WORKDIR $APP_HOME

После этого казалось, что при запуске контейнера переменные среды

Операционная система: macOS (10.14.6)
Версия Docker Desktop: 2.1.0.5 (40693)
Версия движка: 19.03.5
Составьте : 1.24.1

Привет, ребята,

Быстрый вопрос для всех, будет ли это лучший способ создать образ для разработчика? Пока работает нормально. Однако является ли это рекомендуемой практикой? Все изображения основаны на buster.

``
ИЗ redis: buster как redis
ЗАПУСТИТЬ mkdir / env && env> /env/.env_redis
ЗАПУСТИТЬ cat / etc / passwd
RUN ls -lah / home
FROM ruby: тонкий рубин AS
ЗАПУСТИТЬ mkdir / env && env> /env/.env_ruby

ОТ узла: узел AS lts-buster-slim
ЗАПУСТИТЬ mkdir / env && env> /env/.env_node

построить nginx

ОТ nginx: последняя версия AS nginx
ЗАПУСТИТЬ mkdir / env && env> /env/.env_nginx

построить php

С php: fpm-buster AS php

С php: 7.3.14-fpm-buster AS php

ЗАПУСТИТЬ mkdir / env && env> /env/.env_php
КОПИРОВАТЬ --from = redis / /
КОПИРОВАТЬ --from = ruby ​​/ /
КОПИРОВАТЬ --from = node / /
КОПИРОВАТЬ --from = nginx / /

ДОБАВИТЬ conf / include-site.conf /etc/nginx/conf.d/include-site.conf
ДОБАВИТЬ conf / supervisord.conf /etc/supervisord.conf

RUN su root
ВЫБРАТЬ 80 443
WORKDIR "/ var / www / html"

ENTRYPOINT ["/ bin / bash", "/start.sh"]

Проблема все еще существует.
Ключ env_file в разделе сборки будет более понятным, чем передача переменных env через аргументы в сборку контейнера.
Как это:

#NOT_WORKING
build:
      context: ./client
      dockerfile: Dockerfile
      env_file: ${CURRENT_ENV_FILE}

Потому что я использую сценарии оболочки для создания и создания docker compose.
Для производства мне нужен другой env_file, чем для dev / local.
И есть много файлов docker-compose.env.yml со многими аргументами, так что это неудобно, как я думаю

Я думаю, что должен быть какой-то элегантный способ обойти это. Мне очень нравится синтаксис докера, и использование аргументов вместо переменных среды для меня не имеет смысла. Я бы не хотел, чтобы кто-то вручную изменял мои файлы для создания докеров. Мне кажется, что изменение значений в файлах .env согласуется.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги