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

问题描述 投票:1回答:3

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

Dockerfile

FROM alpine:3.9.3

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

env.sh

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客户端安装更长的复杂脚本,该脚本也设置环境变量。如何在不读取整个安装过程并使用dockerfile中的ENV设置所有变量的情况下实现它?

编辑:在实际项目中,文件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安装,因此不会设置变量。

docker dockerfile
3个回答
3
投票

每个Dockerfile RUN步骤都运行一个新容器和一个新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 "

这有三个很好的解决方案。从最简单/最好到最难/最复杂的顺序:

  1. 完全避免需要环境变量。将软件安装到像/usr这样的“系统”位置;无论如何它都会在Docker镜像中被隔离。 (不要使用像Python虚拟环境那样的额外隔离工具,或者像nvmrvm这样的版本管理器;只需安装你需要的特定东西。)
  2. 使用ENV。这将有效: FROM busybox ENV FOO=foo2 ENV BAR=bar CMD echo FOO is $FOO, BAR is $BAR # Prints "FOO is foo2, BAR is bar"
  3. 使用入口点脚本。这通常看起来像: #!/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 inspectdocker exec调试shell中将无法看到通过此方法设置的环境变量;但如果你docker run -it ... sh他们将是可见的。这是一个非常有用且重要的模式,我几乎总是在我的Dockerfiles中使用CMD,除非我特意尝试像这样进行首次设置。

0
投票

我最终在bash脚本中执行了dockerfile的多步构建。

步骤1.设置Dockerfile以包含所有需要为环境变量提供文件的位置。

第2步。在docker文件源中环境变量并将环境回显到文件。

运行源$(pwd)/buildstepenv_rhel72_64.sh && source / opt / rh / devtoolset-8 / enable && env | sort -u> /tmp.env“

第3步使用标记构建图像。

docker build -t $ {image} _dev。

步骤4使用标记运行图像以获取环境变量并将它们添加到docker文件的末尾

docker run --rm $ {image} _dev cat /tmp.env | sed的/ $ /“/; s / = / =”/; s / ^ / ENV /'>> logs / docker / Dockerfile。$ {step}

第5步构造dockerfile的其余部分


-1
投票

这应该够了吧:

RUN export $(cat env.sh | xargs)

希望能帮助到你!

© www.soinside.com 2019 - 2024. All rights reserved.