当前位置: 首页 > 面试题库 >

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

李泓
2023-03-14
问题内容

我正在创建具有类似以下docker项目的问题的映像:

Docker文件

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客户机的源程序提供一个较长的复杂脚本,该脚本还设置了环境变量。如何在不阅读整个安装过程并ENV在dockerfile中设置所有变量的情况下实现它?

编辑:在实际项目中,文件env.sh是在安装过程中创建的,并且不能从容器外部使用。根据在其上执行的系统来设置环境变量。如果我在主机上运行它将在来宾中设置错误的变量。

真实脚本的一部分是

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步骤都运行一个新的容器和一个新的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"
  1. 使用入口点脚本。 通常看起来像:
        #!/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调试环境; 但是,如果您dockerrun-it...sh将它们可见。这是一个有用且足够重要的模式,CMD除非我专门尝试进行此类初次设置,否则我几乎总是在Dockerfile中使用它。



 类似资料:
  • 这个码头商。yml: 使用这个。env文件(它位于根文件夹中,如docker-compose.yml和Dockerfile): 和节点服务器启动中的以下代码: 我真的更喜欢使用第一种或第二种方法 docker版本:18.06.1-CE docker-compose版本:1.19.0

  • 我希望能够在docker compose中使用env变量。yml,值在docker compose up时传入。这就是一个例子。 我今天用基本的docker run命令来做这件事,它包含在我自己的脚本中。有没有一种方法可以在没有任何bash包装器的情况下用compose实现它?

  • 问题内容: 我希望能够在docker-compose.yml中使用env变量,并在docker-compose时传入值。这就是例子。我今天使用基本的docker run命令来执行此操作,该命令包装在我自己的脚本中。没有任何这样的bash包装器,有没有办法通过compose实现它? 问题答案: 创建一个,这是您的with环境变量。 假设您的环境变量在文件“ env.sh”中 将以下代码放入sh文件中

  • 我试图在构建过程中设置docker容器中的环境变量,但没有成功。使用运行命令时设置它们有效,但我需要在构建过程中设置它们。 Dockerfile文件 我用来构建的命令 运行 我正在检查可用的环境变量,通过使用 结果是 TEST_ENV不在场

  • 我希望能够在docker-compose.yml中使用env变量,这些变量的值是在时传入的。这就是例子。 我今天用基本的docker run命令来完成这个任务,它被包装在我自己的脚本中。有没有一种方法可以用compose来实现它,而不需要任何这样的bash包装器?

  • 问题内容: 在“全局属性”中的Jenkins配置(http:// JenkinsURL/configure)中,我定义了一些“环境变量”。 如何在Groovy脚本控制台(http:// JenkinsURL / script)中访问它们? 我试图找到合适的解决方案(例如:[在Jenkins构建步骤(Windows)中从groovy脚本访问构建环境变量中]提到的解决方案),但似乎它们都不适合我。 我