我们可以在通过dockerfile构建docker映像时通过cmd行传递ENV变量吗?


77

我正在执行一项任务,涉及使用DockerfilecentOs为基础构建docker映像。dockerfile内的步骤之一需要设置http_proxyhttps_proxy ENV变量,以便在代理后面工作。

由于此Dockerfile将由具有不同代理的多个团队使用,因此我想避免不必为每个团队编辑Dockerfile。相反,我正在寻找一种解决方案,允许我在构建时传递ENV变量,例如,

sudo docker build -e http_proxy = somevalue。

我不确定是否已经有提供此功能的选项。我想念什么吗?


1
在运行时传递那些有什么问题?像docker run -e http_proxy http://1.2.3.4:3128 -e https_proxy 1.2.3.4:3129什么?docker run docs.docker.com/reference/commandline/run
user2915097

2
问题是,泊坞窗文件中的步骤之一干扰了yum安装,如果我不设置http / https ENV变量,它将失败,并且如果没有正确安装,我将无法生成映像。因此docker run在这里没有帮助我。
Aniketh

恐怕您将不得不构建特定的映像,唯一的区别是http_proxy ONBUILD的值可能会有所帮助,但恐怕它不适合在这里使用,请参阅doc docs.docker.com/reference/builder
user2915097

此处已在github.com/docker/docker/issues/4962中进行了讨论,并在此处再次进行了讨论github.com/docker/docker/pull/9176并已关闭,因此,目前看来您没有解决方案
user2915097 2015年

谢谢user2915097的评论。我已经遍历了上面的github链接,我问这个问题的希望很小,希望Stackoverflow上的某个人可能也遇到过这种情况。
Aniketh

Answers:


119

可以使用build arguments(在Docker 1.9+中)构建容器,其工作方式类似于环境变量。

方法如下:

FROM php:7.0-fpm
ARG APP_ENV=local
ENV APP_ENV ${APP_ENV}
RUN cd /usr/local/etc/php && ln -sf php.ini-${APP_ENV} php.ini

然后构建一个生产容器:

docker build --build-arg APP_ENV=prod .

对于您的特定问题:

FROM debian
ENV http_proxy ${http_proxy}

然后运行:

docker build --build-arg http_proxy=10.11.24.31 .

请注意,如果使用构建容器docker-compose,则可以docker-compose.yml文件中指定这些build-args,但不能在命令行中指定。但是,您可以docker-compose.yml使用环境变量的文件中使用变量替换


8
因为我忽略了它:您需要ARG告知docker可以将build参数传递给构建器。如果未指定ARG <名称>,则无法使用。
马库斯·布鲁克纳

4
ENV APP_ENV ${APP_ENV}是没有必要的。ARG APP_ENV没有=local它就足够了,它将抓住build参数并将其用作由ENV
ElmoVanKielmo

3
@ElmoVanKielmo在构建期间是正确的,但在运行dockerARG映像时不会作为环境变量保留。使用ENV APP_ENV ${APP_ENV}确保在容器运行时环境变量仍然可用。
DuckPuppy

@DuckPuppy是的,但我坚持OP的问题
ElmoVanKielmo

@ElmoVanKielmo OP的问题是关于ENV从命令行传递的,那么ARG独自一人有什么帮助?您需要ARG这样才能通过--build-arg,然后ENV将其复制到环境变量中以与图像保持一致。
haridsv

17

因此,我不得不通过反复试验来解决这个问题,因为许多人解释说您可以通过ARG->,ENV但是它并不总是有效,因为在FROM标签之前还是之后定义ARG都至关重要。

下面的示例应该清楚地说明这一点。我的主要问题原本是我所有的ARGS的被定义之前,FROM这导致所有ENV要始终不确定。

# ARGS PRIOR TO FROM TAG ARE AVAIL ONLY TO FROM for dynamic a FROM tag
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine

# ARGS POST FROM can bond/link args to env to make the containers environment dynamic
ARG NPM_AUTH_TOKEN
ARG EMAIL
ARG NPM_REPO

ENV NPM_AUTH_TOKEN ${NPM_AUTH_TOKEN}
ENV EMAIL ${EMAIL}
ENV NPM_REPO ${NPM_REPO}

# for good measure, what do we really have
RUN echo NPM_AUTH_TOKEN: $NPM_AUTH_TOKEN && \
  echo EMAIL: $EMAIL && \
  echo NPM_REPO: $NPM_REPO && \
  echo $HI_5
# remember to change HI_5 every build to break `docker build`'s cache if you want to debug the stdout

..... # rest of whatever you want RUN, CMD, ENTRYPOINT etc..

3
哇,老兄,我也是!没有人在谈论这个,在文档中没有任何地方提到,警告等!非常感谢!!!
chrizzler

我可能会提到,如果您的部署环境来自自动CI,那么这一点至关重要。当我试图使gitlab CI跨项目域扩展时,我发现了IE。IE One项目可能正在建立一个不同的节点版本,等等...
Nick

2

我面临着同样的情况。

根据Sin30的回答,漂亮的解决方案是使用shell,

CMD ["sh", "-c", "cd /usr/local/etc/php && ln -sf php.ini-$APP_ENV php.ini"]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.