栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何通过dockerfile在ENTRYPOINT之前执行shell命令

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何通过dockerfile在ENTRYPOINT之前执行shell命令

图像是不可变的

Dockerfile定义了映像的构建过程。生成后,图像将是不可变的(无法更改)。运行时变量不会被添加到该不可变映像中。因此,Dockerfile是解决此问题的错误位置。

使用入口点脚本

您可能想做的是

ENTRYPOINT
使用自己的脚本覆盖默认值,并让该脚本对环境变量执行某些操作。由于入口点脚本将在运行时(容器启动时)执行,因此这是收集环境变量并对其进行处理的正确时间。

首先,您需要调整Dockerfile以了解入口点脚本。尽管Dockerfile没有直接参与处理环境变量,但它仍需要了解此脚本,因为该脚本将被烘焙到您的映像中。

Dockerfile:

COPY entrypoint.sh /entrypoint.shRUN chmod +x /entrypoint.shENTRYPOINT ["/entrypoint.sh"]CMD ["npm", "start"]

现在,编写一个入口点脚本,该脚本执行命令运行 之前 所需的一切设置,最后运行

exec
命令本身。

entrypoint.sh:

#!/bin/sh# Where $ENVSUBS is whatever command you are looking to run$ENVSUBS < fil1 > file2npm install# This will exec the CMD from your Dockerfile, i.e. "npm start"exec "$@"

在这里,我已经将包括在内

npm install
,因为您在评论中对此有所询问。我将注意到,这将
npm install
在每次运行时运行
。如果合适的话,很好,但是我想指出一下,它每次都会运行,这会增加启动时间的延迟。

现在重建图像,因此入口点脚本是其中的一部分。

在运行时使用环境变量

入口点脚本知道如何使用环境变量,但是您仍然必须告诉Docker在运行时导入该变量。您可以使用该

-e
标志
docker run
来这样做。

docker run -e "ENVSUBS=$ENVSUBS" <image_name>

在这里,告诉Docker定义一个环境变量

ENVSUBS
,分配给它的值是
$ENVSUBS
当前shell环境中的值。

入口点脚本如何工作

我将对此进行详细说明,因为在评论中,您似乎对此不太了解。

Docker启动容器时,它将在容器内执行一个(只有一个)命令。该命令变得PID
1,就像

init
systemd
典型的Linux系统上。该过程负责运行容器需要具有的任何其他过程。

默认情况下

ENTRYPOINT
/bin/sh -c
。您可以在Dockerfile或docker-
compose.yml中或使用docker命令覆盖它。

启动容器后,Docker运行entrypoint命令,并将命令(

CMD
)作为参数列表传递给它。之前,我们将定义
ENTRYPOINT
/entrypoint.sh
。这意味着在您的情况下,这就是Docker启动时将在容器中执行的操作:

/entrypoint.sh npm start

因为

["npm", "start"]
已被定义为命令,所以这就是作为参数列表传递到入口点脚本的内容。

因为我们使用

-e
标志定义了环境变量,所以此入口点脚本(及其子项)将有权访问该环境变量。

在入口点脚本的末尾,我们运行

exec "$@"
。因为
$@
扩展到传递给脚本的参数列表,所以它将运行

exec npm start

并且由于

exec
将其参数作为命令运行,因此在完成后用其自身 替换 当前进程
npm start
将成为容器中的PID 1。

为什么不能使用多个CMD

在评论中,您询问是否可以定义多个

CMD
条目来运行多个事物。

您只能定义一个

ENTRYPOINT
和一个
CMD
。这些在构建过程中根本不使用。与
RUN
和不同
COPY
,它们在构建期间不会执行。一旦构建,它们就会作为元数据项添加到图像中。

直到稍后,当图像作为容器运行时,这些元数据字段才被读取并用于启动容器。

如前所述,入口点是实际运行的入口点,并将其

CMD
作为参数列表传递。它们分开的原因部分是历史原因。在Docker的早期版本中,它
CMD
是唯一可用的选项,
ENTRYPOINT
并被固定为
/bin/sh-c
。但是由于这种情况,Docker最终
ENTRYPOINT
被用户定义。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/363659.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号