我们可以在通过 dockerfile 构建 docker 映像的同时通过 cmd 行传递 ENV 变量吗?
Posted
技术标签:
【中文标题】我们可以在通过 dockerfile 构建 docker 映像的同时通过 cmd 行传递 ENV 变量吗?【英文标题】:Can we pass ENV variables through cmd line while building a docker image through dockerfile? 【发布时间】:2015-09-20 19:47:46 【问题描述】:我正在处理一项任务,该任务涉及使用 Dockerfile 构建一个以 centOs 为基础的 docker 映像。 dockerfile 中的步骤之一需要设置 http_proxy 和 https_proxy ENV 变量才能在代理后面工作。
由于这个 Dockerfile 将被具有不同代理的多个团队使用,我想避免必须为每个团队编辑 Dockerfile。相反,我正在寻找一种允许我在构建时传递 ENV 变量的解决方案,例如,
sudo docker build -e http_proxy=somevalue .
我不确定是否已经有提供此功能的选项。我错过了什么吗?
【问题讨论】:
在运行时传递这些有什么问题?像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的文档
问题是 docker 文件中的其中一个步骤涉及 yum 安装,如果我不设置 http/https ENV 变量并且没有正确安装,我无法构建图像。所以 docker run 在这里帮不了我。
恐怕您必须构建特定的图像,唯一的区别是 http_proxy(s) ONBUILD 的值可能会有所帮助,但恐怕它不适合这里,请参阅文档docs.docker.com/reference/builder
这已经在这里github.com/docker/docker/issues/4962 和github.com/docker/docker/pull/9176 讨论过并关闭,所以目前看来你没有解决方案
感谢 user2915097 提供的 cmets。我已经浏览了上面的 github 链接,我问这个问题是希望 *** 上的某个人可能遇到过类似的情况。
【参考方案1】:
可以使用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
构建容器,则可以specify these build-args in the docker-compose.yml
file,但不能在命令行上。但是,您可以使用variable substitution in the docker-compose.yml
file, which uses environment variables。
【讨论】:
因为我忽略了它:您需要 ARG 告诉 docker 可以将构建参数传递给构建器。如果不指定 ARGENV APP_ENV $APP_ENV
。有ARG APP_ENV
没有=local
就足够了,它将获取构建参数并将其用作ENV
设置的任何变量
@ElmoVanKielmo 在构建过程中确实如此,但在运行 docker 映像时,ARG
不会作为环境变量持续存在。使用ENV APP_ENV $APP_ENV
可以确保在容器运行时环境变量仍然可用。
@DuckPuppy 是的,但我坚持 OP 的问题
@ElmoVanKielmo OP 的问题是关于从命令行传递ENV
,那么单独使用ARG
有什么帮助?您需要ARG
,以便您可以通过--build-arg
传递一个,然后您需要ENV
将其复制到环境变量以与图像一起保存。【参考方案2】:
我遇到了同样的情况。
根据 Sin30 的回答,漂亮的解决方案是使用 shell,
CMD ["sh", "-c", "cd /usr/local/etc/php && ln -sf php.ini-$APP_ENV php.ini"]
【讨论】:
【参考方案3】:所以我不得不通过反复试验来解决这个问题,因为很多人解释说你可以通过 ARG
-> ENV
但它并不总是有效,因为 ARG 是在FROM
标签。
下面的例子应该清楚地解释这一点。我最初的主要问题是我所有的 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..
【讨论】:
哇,该死,我也遇到了!没有人谈论这个,文档中没有提到,警告等!非常感谢!!! 如果您的部署环境来自自动 CI,我可能会提到这很关键。 IE 当我试图让 gitlab CI 跨项目域进行扩展时,我发现了这一点。 IE 一个项目可能正在解决一个不同的节点版本等... 让我省了些力气,谢谢!我永远不会想到 ARG 的位置很重要.. 我觉得这个其实解释了here:An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM
以上是关于我们可以在通过 dockerfile 构建 docker 映像的同时通过 cmd 行传递 ENV 变量吗?的主要内容,如果未能解决你的问题,请参考以下文章