更新时间:2021-11-30 09:43:52
每个 Dockerfile RUN
步骤运行一个新容器和一个新 shell.如果您尝试在一个 shell 中设置环境变量,稍后它将不可见.例如,您可以试验这个 Dockerfile:
Each Dockerfile RUN
step runs a new container and a new shell. If you try to set an environment variable in one shell, it will not be visible later on. For example, you might experiment with this Dockerfile:
FROM busybox
ENV FOO=foo1
RUN export FOO=foo2
RUN export BAR=bar
CMD echo FOO is $FOO, BAR is $BAR
# Prints "FOO is foo1, BAR is "
对此有三个很好的解决方案.按照从最简单/***到最难/最复杂的顺序:
There are three good solutions to this. In order from easiest/best to hardest/most complex:
完全避免需要环境变量.将软件安装到系统"位置,例如/usr
;无论如何,它将被隔离在 Docker 映像中.(不要使用额外的隔离工具,比如 Python 虚拟环境,或者像 nvm
或 rvm
这样的版本管理器;只需安装你需要的特定东西.)
Avoid needing the environment variables at all. Install software into "system" locations like /usr
; it will be isolated inside the Docker image anyways. (Don’t use an additional isolation tool like Python virtual environments, or a version manager like nvm
or rvm
; just install the specific thing you need.)
使用ENV
.这将工作:
FROM busybox
ENV FOO=foo2
ENV BAR=bar
CMD echo FOO is $FOO, BAR is $BAR
# Prints "FOO is foo2, BAR is bar"
使用入口点脚本.这通常看起来像:
#!/bin/sh
# Read in the file of environment settings
. /opt/wherever/env
# Then run the CMD
exec "$@"
COPY
将此脚本复制到您的 Dockerfile 中.使它成为 ENTRYPOINT
;让 CMD
成为你实际运行的东西.
COPY
this script into your Dockerfile. Make it be the ENTRYPOINT
; make the CMD
be the thing you’re actually running.
FROM busybox
WORKDIR /app
COPY entrypoint.sh .
COPY more_stuff .
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["/app/more_stuff/my_app"]
如果你关心这些事情,你通过这种方法设置的环境变量在 docker inspect
或 docker exec
调试 shell 中是不可见的;但是如果你 docker run -it ... sh
他们将是可见的.这是一个有用且重要的模式,我几乎总是在我的 Dockerfiles 中使用 CMD
,除非我专门尝试像这样进行首次设置.
If you care about such things, environment variables you set via this approach won’t be visible in docker inspect
or a docker exec
debug shell; but if you docker run -it ... sh
they will be visible. This is a useful and important enough pattern that I almost always use CMD
in my Dockerfiles unless I’m specifically trying to do first-time setup like this.