且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 docker 构建过程中使用环境变量获取脚本?

更新时间: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:

  1. 完全避免需要环境变量.将软件安装到系统"位置,例如/usr;无论如何,它将被隔离在 Docker 映像中.(不要使用额外的隔离工具,比如 Python 虚拟环境,或者像 nvmrvm 这样的版本管理器;只需安装你需要的特定东西.)

  1. 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 inspectdocker 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.