Как сделать переменные среды доступными для команд Docker RUN из докеры?

У меня есть приложение Dockerised, которое я хотел бы запускать как в прокси, так и в не-прокси-хост-среде. Я пытаюсь решить эту проблему, скопировав обычные переменные среды, такие как http_proxy, в контейнеры, если и только если они существуют в хосте.

Я могу получить 90% пути, запустив

set | grep -i _proxy=>proxies.env

на верхнем уровне script, а затем, имея в своем файле docker-compose.yml:

myserver:
  build: ./myserver
  env_file:
   - proxies.env

Это копирует переменные прокси-сервера хоста, если они есть, в контейнер сервера, и работает в том смысле, что эти переменные доступны во время выполнения контейнера, другими словами, на этапе, выполняемом Dockerfile CMD или ENTRYPOINT.

Однако у меня есть один контейнер, который должен запускать npm в качестве шага сборки, то есть из команды RUN в файле Docker, и эти переменные, кажется, не присутствуют на этом этапе, поэтому npm не может найти прокси и зависает. В других работах, если у меня есть

RUN set

в моем файле Docker, я не вижу никаких переменных из proxies.env, но если я делаю

docker exec -it myserver /bin/bash

а затем запустите set, я вижу все, начиная с proxies.env.

Может ли кто-нибудь рекомендовать способ сделать эти переменные видимыми во время сборки контейнера без необходимости их жесткого кодирования, чтобы мои файлы docker-compose.yml и Dockerfile по-прежнему работали как для хостов с прокси-серверами и хостами без прокси-серверов?

(Работа с centos 7, сборка докеров 1.3.1 и докер 1.7.0)

Ответ 1

Возможно, вы можете попробовать следующее:

Прежде чем вы вызовете RUN, ADD.ENV файл в изображение

ADD proxies.env proxies.env

затем префикс вашего оператора RUN:

RUN export `cat proxies.env` && echo "FOO is $FOO and BAR is $BAR"

Это приводит к следующему выводу:

[email protected]:~/Dockers/set-env# docker build -t ashimoon/envtest .
Sending build context to Docker daemon 3.584 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu
 ---> 91e54dfb1179
Step 1 : ADD proxies.env proxies.env
 ---> Using cache
 ---> 181d0e082e65
Step 2 : RUN export `cat proxies.env` && echo "FOO is $FOO and BAR is $BAR"
 ---> Running in 30426910a450
FOO is 1 and BAR is 2
 ---> 5d88fcac522c
Removing intermediate container 30426910a450
Successfully built 5d88fcac522c

Ответ 2

Обновление 2016, docker-compose 1.6.2, docker 1.10+, с docker-compose.yml версия 2:

Теперь у вас есть раздел args: раздела build:, который включает это очень интересная возможность:

Аргументы сборки только с ключом разрешены к их значению среды на машине. Работа выполняется на.

См. PR 2653 (январь 2016 г.)

В результате способ введения прокси-переменных без жесткого кодирования в самом файле docker-compose.yml заключается в этом точном синтаксисе:

version: '2'
services:
  myservice:
    build:
      context: .
      args:
        - http_proxy
        - https_proxy
        - no_proxy

Перед вызовом docker-compose вверх необходимо убедиться, что переменные среды прокси установлены:

export http_proxy=http://username:[email protected]:port
export https_proxy=http://username:[email protected]:port
export no_proxy=localhost,127.0.0.1,company.com

docker-compose up

Затем ваш Dockerfile, созданный процессом docker-compose, автоматически подберет значения прокси-переменной, даже если docker-compose.yml не содержит жестко заданных конкретных значений.

Ответ 3

Может быть, опция "окружающая среда" решает вашу проблему. В файле сокета docker будет выглядеть:

myserver:
   build: ./myserver
   environment:
   - HTTP_PROXY=192.168.1.8
   - VARIABLE=value
   - ...

Ответ 4

docker-compose.yml

...
server:
  build: .
  args:
    env: $ENV
...

Dockerfile

ARG env

ENV NODE_ENV $env

Ответ 5

В этом примере исправлено YUM.

version: '2'
services:  
  example-service:
    build:
      context: .
      args:
        http_proxy: proxy.example.com:80