Dockerfile中的CMD和ENTRYPOINT

Shell格式和Exec格式

Dockerfile中,RUNCMDENTRYPOINT指令都可以使用两种格式:Shell格式Exec格式

  • exec 格式INSTRUCTION ["executable","param1","param2"]
  • shell 格式INSTRUCTION command param1 param2

exec格式使得避免使用shell字符串处理成为可能,并且可以使用特定的命令shell或任何其他可执行文件来调用命令。它使用JSON数组语法,数组中的每个元素都是一个命令、标志或参数。

shell格式更加灵活,强调易用性、灵活性和可读性。

在使用shell格式时系统会自动选择一个命令shell来执行指令,而在使用exec格式时,需要明确指定使用哪个命令shell或其他可执行文件来执行命令。换句话说,shell格式会自动选择执行环境,而exec格式需要手动指定执行环境。

Exec 格式

Exec格式被解析为一个JSON数组,这意味着你必须使用双引号(")而不是单引号(')来包围单词。

ENTRYPOINT ["/bin/bash", "-c", "echo hello"]

Exec格式最适合用于指定ENTRYPOINT指令,并结合CMD来设置可以在运行时覆盖的默认参数。

变量替换

使用Exec格式不会自动调用命令shell。这意味着不会发生常规的shell处理,例如变量替换。例如,RUN [ "echo", "$HOME" ]不会处理$HOME的变量替换。

如果你想进行shell处理,可以使用Shell格式,或者直接在Exec格式中执行shell,例如:RUN [ "sh", "-c", "echo $HOME" ]。当使用Exec格式并直接执行shell时,就像Shell格式一样,是由shell进行环境变量替换,而不是构建器。

反斜杠

在Exec格式中,你必须对反斜杠进行转义。这在Windows上特别重要,因为在Windows中反斜杠是路径分隔符。以下行将因未被视为有效的JSON而被视为Shell格式,并以意外的方式失败:

RUN ["c:\windows\system32\tasklist.exe"]

正确的语法示例是:

RUN ["c:\\windows\\system32\\tasklist.exe"]

Shell 格式

与Exec格式不同,使用Shell格式的指令总是使用命令shell。Shell格式不使用JSON数组格式,而是一个常规的字符串。Shell格式字符串允许你使用转义字符(默认是反斜杠)来换行,将单个指令延续到下一行。这使得它更容易用于更长的命令,因为它允许你将它们分割成多行。例如,考虑以下两行:

RUN source $HOME/.bashrc && \
echo $HOME

它们等同于以下单行:

RUN source $HOME/.bashrc && echo $HOME

你可以使用heredocs与Shell格式来拆分命令:

RUN <<EOF
source $HOME/.bashrc && \
echo $HOME
EOF

使用不同的shell

你可以使用SHELL命令更改默认shell。例如:

SHELL ["/bin/bash", "-c"]
RUN echo hello

CMD

CMD指令设置了在从镜像运行容器时要执行的命令。

你可以使用shell格式或exec格式来指定CMD指令:

  • CMD ["executable","param1","param2"](exec格式)
  • CMD ["param1","param2"](exec格式,作为ENTRYPOINT的默认参数)
  • CMD command param1 param2(shell格式)
    Dockerfile中只能有一个CMD指令。如果列出多个CMD,只有最后一个会生效。

CMD的目的是为正在执行的容器提供默认值。这些默认值可以包括一个可执行文件,也可以省略可执行文件,此时你必须同时指定ENTRYPOINT指令。

如果你希望容器每次运行时都执行相同的可执行文件,那么你应该考虑结合使用ENTRYPOINTCMD。如果用户在docker run中指定了参数,它们将覆盖在CMD中指定的默认值,但仍会使用默认的ENTRYPOINT

如果CMD用于为ENTRYPOINT指令提供默认参数,则应该以exec格式指定CMDENTRYPOINT指令。

注意 不要将RUN与CMD混淆。RUN实际上运行一个命令并提交结果;CMD不会在构建时执行任何操作,而是为镜像指定预期的命令。

ENTRYPOINT

ENTRYPOINT 允许您配置一个将作为可执行文件运行的容器。

ENTRYPOINT 有两种可能的格式:

  • 首选的 exec 格式:
ENTRYPOINT ["executable", "param1", "param2"]
  • shell 格式:
ENTRYPOINT command param1 param2

以下命令从带有默认内容、监听端口 80 的 nginx 启动容器:

docker run -i -t --rm -p 80:80 nginx

对于 docker run <image> 的命令行参数将附加在 exec 格式的 ENTRYPOINT 中的所有元素之后,并将覆盖使用 CMD 指定的所有元素。这允许将参数传递给入口点,即 docker run <image> -d 将向入口点传递 -d 参数。您可以使用 docker run --entrypoint 标志覆盖 ENTRYPOINT 指令。

ENTRYPOINT 的 shell 格式阻止使用任何 CMD 命令行参数。它还将您的 ENTRYPOINT 作为 /bin/sh -c 的子命令启动,不会传递信号。这意味着可执行文件不会成为容器的 PID 1,并且不会接收 Unix 信号。在这种情况下,您的可执行文件不会从 docker stop <container> 接收 SIGTERM 信号。

Dockerfile 中的最后一个 ENTRYPOINT 指令将生效。

Exec 格式的 ENTRYPOINT 示例

您可以使用 exec 格式的 ENTRYPOINT 来设置相对稳定的默认命令和参数,然后使用 CMD 的任一格式来设置更有可能被更改的其他默认值。

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

当您运行容器时,您可以看到top是唯一的进程:

docker run -it --rm --name test  top -H

top - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffers
KiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

要进一步检查结果,您可以使用docker exec:

docker exec -it test ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  2.6  0.1  19752  2352 ?        Ss+  08:24   0:00 top -b -H
root         7  0.0  0.1  15572  2164 ?        R+   08:25   0:00 ps aux

您可以使用docker stop test优雅地请求top关闭。

以下Dockerfile显示使用ENTRYPOINT在前台运行Apache(即作为PID 1):

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

如果您需要为单个可执行文件编写启动脚本,您可以使用execgosu命令确保最终可执行文件接收Unix信号:

#!/usr/bin/env bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

最后,如果您需要在关闭时进行一些额外的清理(或与其他容器通信),或者协调多个可执行文件,您可能需要确保ENTRYPOINT脚本接收Unix信号,传递它们,然后执行更多工作:

#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too

# USE the trap if you need to also do manual cleanup after the service is stopped,
#     or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM

# start service in background here
/usr/sbin/apachectl start

echo "[hit enter key to exit] or run 'docker stop <container>'"
read

# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop

echo "exited $0"

如果您使用docker run -it --rm -p 80:80 --name test apache运行此映像,则可以使用docker execdocker top检查容器的进程,然后要求脚本停止Apache:

docker exec -it test ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0   4448   692 ?        Ss+  00:42   0:00 /bin/sh /run.sh 123 cmd cmd2
root        19  0.0  0.2  71304  4440 ?        Ss   00:42   0:00 /usr/sbin/apache2 -k start
www-data    20  0.2  0.2 360468  6004 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
www-data    21  0.2  0.2 360468  6000 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
root        81  0.0  0.1  15572  2140 ?        R+   00:44   0:00 ps aux

docker top test

PID                 USER                COMMAND
10035               root                {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054               root                /usr/sbin/apache2 -k start
10055               33                  /usr/sbin/apache2 -k start
10056               33                  /usr/sbin/apache2 -k start

/usr/bin/time docker stop test

test
real	0m 0.27s
user	0m 0.03s
sys	0m 0.03s

Shell 格式 ENTRYPOINT 示例

您可以为ENTRYPOINT指定一个纯字符串,它将在 /bin/sh-c中执行。此表单将使用shell处理来替换shell环境变量,并将忽略任何CMDdocker run命令行参数。为了确保docker stop将正确地发出任何长时间运行的ENTRYPOINT可执行文件的信号,您需要记住以exec开头:

FROM ubuntu
ENTRYPOINT exec top -b

当您运行此映像时,您将看到单个PID 1进程:

docker run -it --rm --name test top

Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU:   5% usr   0% sys   0% nic  94% idle   0% io   0% irq   0% sirq
Load average: 0.08 0.03 0.05 2/98 6
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
    1     0 root     R     3164   0%   0% top -b

在docker stop上干净地退出:

/usr/bin/time docker stop test

test
real	0m 0.20s
user	0m 0.02s
sys	0m 0.04s

如果您忘记将exec添加到ENTRYPOINT的开头:

FROM ubuntu
ENTRYPOINT top -b
CMD -- --ignored-param1

然后,您可以运行它(为下一步命名):

docker run -it --name test top --ignored-param2

top - 13:58:24 up 17 min,  0 users,  load average: 0.00, 0.00, 0.00
Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 16.7 us, 33.3 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1990.8 total,   1354.6 free,    231.4 used,    404.7 buff/cache
MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.   1639.8 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0    2612    604    536 S   0.0   0.0   0:00.02 sh
    6 root      20   0    5956   3188   2768 R   0.0   0.2   0:00.00 top

您可以从top的输出中看到指定的ENTRYPOINT不是PID 1

如果您随后运行docker stop test,容器将不会干净地退出-stop命令将在超时后强制发送SIGKILL

docker exec -it test ps waux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.4  0.0   2612   604 pts/0    Ss+  13:58   0:00 /bin/sh -c top -b --ignored-param2
root         6  0.0  0.1   5956  3188 pts/0    S+   13:58   0:00 top -b
root         7  0.0  0.1   5884  2816 pts/1    Rs+  13:58   0:00 ps waux

/usr/bin/time docker stop test

test
real	0m 10.19s
user	0m 0.04s
sys	0m 0.03s

了解CMD和ENTRYPOINT如何交互

CMDENTRYPOINT指令都定义了在运行容器时执行的命令。描述它们合作的规则很少。

  1. Dockerfile应至少指定一个CMDENTRYPOINT命令。
  2. 将容器用作可执行文件时应定义ENTRYPOINT
  3. CMD应该用作定义ENTRYPOINT命令或在容器中执行 ad-hoc 命令的默认参数的一种方式。
  4. 使用替代参数运行容器时,CMD将被覆盖。

下表显示了对不同的ENTRYPOINT/CMD组合执行的命令:

No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]
No CMDerror, not allowed/bin/sh -c exec_entry p1_entryexec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”]exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry exec_cmd p1_cmd
CMD exec_cmd p1_cmd/bin/sh -c exec_cmd p1_cmd/bin/sh -c exec_entry p1_entryexec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

Note: 如果从基本图像定义了CMD,则设置ENTRYPOINT会将CMD重置为空值。在这种情况下,必须在当前图像中定义CMD才能具有值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/605430.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯【第15届省赛】Python B组 32.60 分

F 题列表越界访问了……省一但没什么好名次 测评链接&#xff1a;https://www.dotcpp.com/oj/train/1120/ C 语言网真是 ** 测评&#xff0c;时间限制和考试的不一样&#xff0c;E 题给我整时间超限&#xff1f; A&#xff1a;穿越时空之门 100&#x1f3c6; 【问题描述】 随…

简要介绍三大脚本语言 Shell、Python 和 Lua

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 脚本语言是一种用于自动化操作系统任务和应用程序功能的编程语言。它们通常用于编写小到中等规模的程序&#xff0c;以提高任务执行的速度和效率。在众多脚本语言中&#xff0c;Shell、Python 和 Lua 是…

Python | Leetcode Python题解之第77题组合

题目&#xff1a; 题解&#xff1a; class Solution:def combine(self, n: int, k: int) -> List[List[int]]:ans []path []def dfs(x):remain k - len(path)if not remain:ans.append(list(path))returnif n 1 - x > remain:dfs(x 1)path.append(x)dfs(x 1)path.…

工业级路由器的穿透力是不是更强(原创科普)

今天我想和大家聊聊工业级路由器的一个重要特性——穿透力。作为一名从事工业网络通信的工程师,我发现很多用户在选择工业级路由器时,都会问到一个问题:"工业级路由器的穿透力是不是更强?"下面就让我来为大家解答这个疑问。当然如果有通信产品需要也可以关注星创易联…

09 - 数据清洗案例

流程图 kettle 面板图片 操作步骤 1、订阅数据源&#xff08;kafka consumer&#xff09; 2、抽取字段并转换key&#xff08;JSON input&#xff09; 3、判断img字段是否有值&#xff0c;有的话进行url转base64&#xff08;JavaScript 代码&#xff09; // 获取输入字段的值 v…

中金:如何把握不断轮动的资产“风口”

从比特币到日股&#xff0c;到黄金与铜再到当前的港股&#xff0c;每次超预期大涨后都透支回调。 今年以来资产的“风口”不断轮动&#xff0c;从比特币到日股&#xff0c;到黄金与铜&#xff0c;再到当前的港股&#xff0c;资产仿佛“接力”般交替领先&#xff0c;同时“风口”…

JavaScript 垃圾回收机制深度解析:内存管理的艺术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f3ad; 引言一、JavaScript内存模型与生命周期的深度解析&#x1f4cc; 基本数据类型与栈内存的精妙运作&#x1f4cc; 复杂数据类型与堆内存的广袤世界&#x1f4cc; 生命周期管理的智慧与实践策略&#x1f4cc; We…

uniapp开发小程序使用vue的v-html解析富文本图片过大过宽显示超过屏幕解决办法

如果没有设置的话&#xff0c;就会导致图片溢出&#xff0c;过宽显示或者错位显示&#xff0c;显示效果非常的丑陋&#xff1a; 修改后显示的效果&#xff1a; 网上比较low的解决办法&#xff1a;网上各种解决方法核心思想就是在数据层把数据模板上的img数据加上style样式&…

嵌入式Linux学习第四天启动方式学习

嵌入式Linux学习第四天 今天学习I.MX6U 启动方式详解。I.MX6U有多种启动方式&#xff0c;可以从 SD/EMMC、NAND Flash、QSPI Flash等启动。 启动方式选择 BOOT 的处理过程是发生在 I.MX6U 芯片上电以后&#xff0c;芯片会根据 BOOT_MODE[1:0]的设置来选择 BOOT 方式。BOOT_M…

windows11获取笔记本电脑电池健康报告

笔记本电脑的电池关系到我们外出时使用的安全&#xff0c;如果电池健康有问题需要及时更换&#xff0c;windows系统提供了检查电池健康度的方法。 1、打开命令行 1&#xff09;键入 winR 2&#xff09;键入 cmd 打开命令行。 2、在命令行运行如下指令&#xff0c;生成电池健…

Maven+Junit5 + Allure +Jenkins 搭建 UI 自动化测试实战

文章目录 效果展示Junit 5Junit 5 介绍Junit 5 与 Junit 4 对比PageFactory 模式编写自动化代码公共方法提取测试用例参数化Jenkins 搭建及配置参数化执行生成 Allure 报告Maven 常用命令介绍POM 文件效果展示 本 chat 介绍 UI 自动化测试框架的搭建: 运用 page factory 模式…

TCP三次握手四次挥手 UDP

TCP是面向链接的协议&#xff0c;而UDP是无连接的协议 TCP的三次握手 三次传输过程是纯粹的不涉及数据&#xff0c;三次握手的几个数据包中不包含数据内容。它的应用层&#xff0c;数据部分是空的&#xff0c;只是TCP实现会话建立&#xff0c;点到点的连接 TCP的四次挥手 第四…

介绍 ffmpeg.dll 文件以及ffmpeg.dll丢失怎么办的五种修复方法

ffmpeg.dll 是一个动态链接库文件&#xff0c;属于 FFmpeg运行库。它在计算机上扮演着非常重要的角色&#xff0c;因为它提供了许多应用程序和操作系统所需的功能和组件。当 ffmpeg.dll 文件丢失或损坏时&#xff0c;可能会导致程序无法正常运行&#xff0c;甚至系统崩溃。下面…

基于opencv的车辆统计

车辆统计&#xff09; 一、项目背景二、整体流程三、常用滤波器的特点四、背景减除五、形态学开运算闭运算 六、项目完整代码七、参考资料 一、项目背景 检测并识别视频中来往车辆的数量 最终效果图&#xff1a; 二、整体流程 加载视频图像预处理&#xff08;去噪、背景减除…

航空电子FC节点卡, FC交换机,主要采用LC或MPO光纤接口形式

FC节点卡主要采用LC或MPO光纤接口形式&#xff0c;可以作为4/2个独立端口使用&#xff0c;也可以作为2对/1对冗余端口使用&#xff0c;支持1.0625Gbps、2.125Gbps、4.25Gbps、8.5Gbps通信速率。节点卡完全遵循FC-LS&#xff0c;FC-FS&#xff0c;FC-AE-ASM、FC-AE-1553B等FC光纤…

springboot+vue+mybatis家教管理系统的设计与实现+PPT+论文+讲解+售后

家教管理系统是为了方便用户能够在网站上查看教师信息进行家教预约等&#xff0c;于是开发了基于springboot框架设计与实现了一款简洁、轻便的家教管理系统。本系统解决了家教管理事务中的主要问题&#xff0c;包括以下多个功能模块&#xff1a;公告信息、留言信息、预约家教老…

Isaac Sim 4 键盘控制小车前进方向(学习笔记5.8.2)

写的乱糟糟&#xff0c;主要是这两周忘了记录了...吭哧吭哧往下搞&#xff0c;突然想起来要留档&#xff0c;先大致写一个&#xff0c;后面再往里添加和修改吧&#xff0c;再不写就全忘了 有一个一直没解决的问题&#xff1a; 在保存文件时出现问题&#xff1a;isaac sim mism…

【OceanBase诊断调优】—— 磁盘性能问题导致卡合并和磁盘写入拒绝排查

适用版本 OceanBase 数据库 V3.x、V4.x 版本。 问题现象 OceanBase 集群合并一直未完成&#xff0c;同时 tsar 和 iostat 显示从凌晨 2:30 开始磁盘使用率一直是 100%。怀疑合并导致 IO 上升&#xff0c;IO 可能存在问题&#xff0c;observer.log 的确有大量报错 disk is hu…

概述篇——计算机网络学习笔记(基于谢希仁教材与PPT)

教材用的是谢希仁的教材&#xff0c;图片来源于谢希仁老师配套的PPT 计算机网络课程PPT&#xff08;通过这个链接&#xff0c;你可以找到课程配套的ppt&#xff09; 计算机网络的定义及其特点 定义 网络 过去大众熟知的三种网络分别是提供电话、电报及传真等服务的电信网络&am…

Linux主机排查工具-GScan

0x01 简介 本程序旨在为安全应急响应人员对Linux主机排查时提供便利&#xff0c;实现主机侧Checklist的自动全面化检测&#xff0c;根据检测结果自动数据聚合&#xff0c;进行黑客攻击路径溯源。 0x02 项目地址 https://github.com/grayddq/GScan 0x03 CheckList检测项 自…
最新文章