【问题标题】:How to make environmental variables available to Docker RUN commands from docker-compose?如何使环境变量可用于来自 docker-compose 的 Docker RUN 命令?
【发布时间】:2015-09-21 11:53:33
【问题描述】:

我有一个 Dockerised 应用程序,我想在代理和非代理主机环境中运行。我试图通过将普通环境变量(例如 http_proxy)复制到容器中来解决此问题,当且仅当它们存在于主机中时。

我可以通过跑步到达那里的 90%

set | grep -i _proxy=>proxies.env

在顶级脚本中,然后在我的 docker-compose.yml 中:

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

这会将主机的环境代理变量(如果有)复制到服务器容器中,并且它的工作原理是这些变量在容器运行时可用,换句话说,在 Dockerfile CMD 或 ENTRYPOINT 执行的阶段可用。

但是,我有一个容器需要运行 npm 作为构建步骤,即来自 Dockerfile 中的 RUN 命令,而这些变量在此阶段似乎不存在,因此 npm 找不到代理并挂起。在其他作品中,如果我有

RUN set

在我的 Dockerfile 中,我看不到 proxies.env 中的任何变量,但如果我看到了

docker exec -it myserver /bin/bash

然后运行 ​​set,我可以看到 proxies.env 中的所有内容。

谁能推荐一种在容器构建时使这些变量可见的方法,而不必对它们进行硬编码,这样我的 docker-compose.yml 和 Dockerfile 仍然适用于有代理的主机和没有代理的主机?

(使用 centos 7、docker-compose 1.3.1 和 docker 1.7.0 运行)

【问题讨论】:

  • 使用预定义的 env 变量生成 docker 文件对我来说似乎是最简单的方法。
  • 你可能是对的。在没有更好的建议的情况下,我将整理一个 shell 脚本,该脚本将使用 sed 填充或注释掉硬编码的 NPM sed 设置,这样我就可以对云和企业主机使用相同的 Dockerfile。跨度>
  • 更新:docker-compose.yml 版本 2 (docker 1.10+),您现在有一个更好的选择:build:/args:。见my answer below

标签: proxy docker docker-compose


【解决方案1】:

也许你的“环境”选项可以解决你的问题。在你的 docker compose 文件中看起来像:

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

【讨论】:

  • 请问什么版本的 yml?
【解决方案2】:

也许你可以试试这个:

在调用RUNADD 之前将 .env 文件导入图像

ADD proxies.env proxies.env

然后为您的 RUN 语句添加前缀:

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

这会产生以下输出:

root@armenubuntudev:~/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

【讨论】:

  • 我们不能做 ENV ENV JAVA_HOME $(alternatives --list | grep javac | awk '{print $3}' | sed -e "s/\/bin\/javac//g" ) ????
  • 这解决了我的问题——它使 env 变量在容器构建时可用
  • 这个答案解决了问题,请注意这打破了创建docker images的哲学......
  • 我必须在需要 env 文件值的每个单独的“运行”处进行导出。希望我们将来能找到更好的解决方案,但就目前而言,让它发挥作用对我来说已经足够了。
【解决方案3】:

2016 年更新,docker-compose 1.6.2,docker 1.10+,docker-compose.yml version 2

您现在拥有build: sectionargs: sub-section,其中包括非常有趣的可能性:

只有一个键的构建参数在 Compose 运行的机器上解析为它们的环境值

PR 2653(2016 年 1 月)

因此,在docker-compose.yml 文件本身中引入代理变量而不用硬编码的方法就是使用这种精确的语法:

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

在调用 docker-compose up 之前,你需要确保你的代理环境变量已经设置好:

export http_proxy=http://username:password@proxy.com:port
export https_proxy=http://username:password@proxy.com:port
export no_proxy=localhost,127.0.0.1,company.com

docker-compose up

然后,您由docker-compose 进程构建的Dockerfile 将自动获取代理变量值,即使docker-compose.yml 不包含任何硬编码的特定值。

【讨论】:

  • 如果主机环境不能提供构建参数并且不是通过 cli 提供的会发生什么?
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2015-06-17
    • 2019-10-06
    • 2022-08-16
    • 2016-09-08
    • 1970-01-01
    • 2019-07-26
    相关资源
    最近更新 更多