gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 00:53:42 25 4
gpt4 key购买 nike

我正在创建一个具有类似问题的图像,如以下 docker 项目:

文件

FROM alpine:3.9.3

COPY ./env.sh /env.sh
RUN source /env.sh
CMD env

环境文件
TEST=test123

我用
docker build -t sandbox .

并运行它
docker run --rm sandbox

输出是
HOSTNAME=72405c43801b
SHLVL=1
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

我的环境变量丢失了。

在实际项目中,我必须为 IBM DB2 客户端的安装提供更长的复杂脚本,该脚本还设置了环境变量。如何在不阅读整个安装过程并使用 ENV 设置所有变量的情况下实现它在 dockerfile 中?

编辑:
在实际项目中文件 env.sh是作为安装过程的一部分创建的,不能从容器外部使用。环境变量的设置取决于它在其上执行的系统。如果我在主机上运行它,它会在 guest 中设置错误的变量。

真实脚本的一部分是
if [ -f ${INST_DIR?}/tools/clpplus.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/clpplus.jar a
fi

if [ -f ${INST_DIR?}/tools/antlr-3.2.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/antlr-3.2.jar a
fi

if [ -f ${INST_DIR?}/tools/jline-0.9.93.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/jline-0.9.93.jar a
fi

if [ -f ${INST_DIR?}/java/db2jcc.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/java/db2jcc.jar a
fi

if [ -f ${INST_DIR?}/java/db2jcc_license_cisuz.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/java/db2jcc_license_cisuz.jar a
fi

它检查安装并根据此设置变量。由于主机上没有安装 DB2,因此不会设置变量。

最佳答案

每个 Dockerfile RUN step 运行一个新容器和一个新 shell 。如果您尝试在一个 shell 中设置环境变量,那么稍后它将不可见。例如,您可以试验这个 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 "

对此有三个很好的解决方案。按照从最简单/最好到最难/最复杂的顺序:
  • 完全避免需要环境变量。 将软件安装到“系统”位置,例如 /usr ;无论如何,它将被隔离在 Docker 镜像中。 (不要使用额外的隔离工具,比如 Python 虚拟环境,或者版本管理器,比如 nvmrvm ;只需安装你需要的特定东西。)
  • 使用 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成为你真正在运行的东西。
    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他们将是可见的。这是一个有用且重要的模式,我几乎总是使用 CMD在我的 Dockerfiles 中,除非我特别想像这样进行首次设置。
  • 关于docker - 如何在 docker 构建过程中使用环境变量获取脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55921914/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com