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 -Htop - 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 MemPID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

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

docker exec -it test ps auxUSER       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 -eif [ "$1" = 'postgres' ]; thenchown -R postgres "$PGDATA"if [ -z "$(ls -A "$PGDATA")" ]; thengosu postgres initdbfiexec gosu postgres "$@"
fiexec "$@"

最后,如果您需要在关闭时进行一些额外的清理(或与其他容器通信),或者协调多个可执行文件,您可能需要确保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 startecho "[hit enter key to exit] or run 'docker stop <container>'"
read# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stopecho "exited $0"

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

docker exec -it test ps auxUSER       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 auxdocker top testPID                 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 testtest
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 topMem: 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 6PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND1     0 root     R     3164   0%   0% top -b

在docker stop上干净地退出:

/usr/bin/time docker stop testtest
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-param2top - 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 MemPID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND1 root      20   0    2612    604    536 S   0.0   0.0   0:00.02 sh6 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 wauxUSER       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 testtest
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.mzph.cn/web/10629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深耕 Python】Quantum Computing 量子计算机(5)量子物理概念(二)

写在前面 往期量子计算机博客&#xff1a; 【深耕 Python】Quantum Computing 量子计算机&#xff08;1&#xff09;图像绘制基础 【深耕 Python】Quantum Computing 量子计算机&#xff08;2&#xff09;绘制电子运动平面波 【深耕 Python】Quantum Computing 量子计算机&…

ios 开发如何给项目安装第三方库,以websocket库 SocketRocket 为例

1.brew 安装 cococapods $ brew install cocoapods 2、找到xcode项目 的根目录&#xff0c;如图&#xff0c;在根目录下创建Podfile 文件 3、在Podfile文件中写入 platform :ios, 13.0 use_frameworks! target chat_app do pod SocketRocket end project ../chat_app.x…

Python实战开发及案例分析(18)—— 逻辑回归

逻辑回归是一种广泛用于分类任务的统计模型&#xff0c;尤其是用于二分类问题。在逻辑回归中&#xff0c;我们预测的是观测值属于某个类别的概率&#xff0c;这通过逻辑函数&#xff08;或称sigmoid函数&#xff09;来实现&#xff0c;该函数能将任意值压缩到0和1之间。 逻辑回…

Leetcode 572:另一颗树的子树

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的…

【linux】详解linux基本指令

目录 cat more less head tail 时间 cal find grep zip/unzip tar bc uname –r 关机 小编一共写了两篇linux基本指令&#xff0c;这两篇涵盖了大部分初学者的必备指令&#xff0c;这是第二篇&#xff0c;第一篇详见http://t.csdnimg.cn/HRlVt cat 适合查看小文…

网站localhost和127.0.0.1可以访问,本地ip不可访问解决方案

部署了一个网站, 使用localhost和127.0.0.1加端口号可以访问, 但是使用本机的ip地址加端口号却不行. 原因可能有多种. 可能的原因: 1 首先要确认是否localhost对应的端口是通的(直接网址访问), 以及你无法访问的那个本机ip是否正确(使用ping测试)&#xff1b; 2 检查本机的防火…

从头理解transformer,注意力机制(下)

交叉注意力 交叉注意力里面q和KV生成的数据不一样 自注意力机制就是闷头自学 解码器里面的每一层都会拿着编码器结果进行参考&#xff0c;然后比较相互之间的差异。每做一次注意力计算都需要校准一次 编码器和解码器是可以并行进行训练的 训练过程 好久不见输入到编码器&…

docker部署springboot+Vue项目

项目介绍&#xff1a;后台springboot项目&#xff0c;该项目环境mysql、redis 。前台Vue&#xff1a;使用nginx反向代理 方法一&#xff1a;docker run 手动逐个启动容器 1.docker配置nginx代理 将vue项目打包上传到服务器上。创建文件夹存储数据卷&#xff0c;html存放打包…

计算机网络实验1:交换机基本配置管理

实验目的和要求 安装Packer Tracer&#xff0c;了解Packer Tracer的基本操作掌握交换机基本命令集实验项目内容 认识Packet Tracer软件 交换机的基本配置与管理 交换机的端口配置与管理 交换机的端口聚合配置 交换机划分Vlan配置 实验环境 硬件&#xff1a;PC机&#x…

Redisson分布式锁原理

Redisson是基于Redis实现的客户端库&#xff0c;提供了多种Java并发API映射到Redis中&#xff0c;也实现了各种分布式服务&#xff0c;其中就有各种分布式锁的实现。 Redisson锁弥补了SETNX锁的的局限性&#xff0c;实现了可重入、可重试和超时续约的功能。 可重入&#xff1a…

解决NVM 下载node.js慢问题->最新镜像

一、NVM 介绍 nvm是node版本管理工具&#xff0c;可以运行在多种操作系统上。这里主要记录一下在windows系统的安装和使用。 在使用过程中&#xff0c;下载其他版本时会出现下载慢或卡住或下载失败的情况&#xff0c;是因为服务器在国外&#xff0c;网络原因导致&#xff0c;…

代码随想录Day 41|Leetcode|Python|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

198.打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

在统计上城乡是如何划分的

城乡二元结构&#xff0c;是长期以来我国经济社会发展的显著特点之一&#xff0c;党和政府高度重视统筹城乡发展&#xff0c;缩小城乡差距。为了对城乡发展予以准确反映和动态监测&#xff0c;提高在统计上划分城乡工作的一致性&#xff0c;国家统计局开展了统一的统计用区划代…

【Docker学习】docker run的端口映射-p和-P选项

docker run的端口映射选项分为-p&#xff08;小写&#xff0c;全称--publish&#xff09;&#xff0c;-P&#xff08;大写&#xff0c;全称--publish-all&#xff09;&#xff0c;之前认为只有改变容器发布给宿主机的默认端口号才会进行-p的设置&#xff0c;而不改变默认端口号…

面试经典算法系列之数组/字符串6 -- 轮转数组

面试经典算法题38-轮转数组 LeetCode.189 公众号&#xff1a;阿Q技术站 问题描述 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 …

YOLOv8训练流程-原理解析[目标检测理论篇]

关于YOLOv8的主干网络在YOLOv8网络结构介绍-CSDN博客介绍了&#xff0c;为了更好地学习本章内容&#xff0c;建议先去看预测流程的原理分析YOLOv8原理解析[目标检测理论篇]-CSDN博客&#xff0c;再次把YOLOv8网络结构图放在这里&#xff0c;方便随时查看。 ​ 1.前言 YOLOv8训练…

Map中KEY去除下划线并首字母转换为大写工具类

在运维旧项目时候&#xff0c;碰上sql查询结果只能返回List<Map>&#xff0c;key为表单字段名&#xff0c;value为获取到的结果数据。 懒得一个一个敲出来&#xff0c;就直接写个方法转换&#xff0c;并赋值到相应实体对象里去。 Map中KEY去除下划线并首字母转换为大写&…

算法提高之矩阵距离

算法提高之矩阵距离 核心思想&#xff1a;多源bfs 从多个源头做bfs&#xff0c;求距离 先把所有1的坐标存入队列 再把所有1连接的位置存入 一层一层求 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 1…

Kafka 面试题(八)

1. Kafka&#xff1a;硬件配置选择和调优的建议 &#xff1f; Kafka的硬件配置选择和调优是确保Kafka集群高效稳定运行的关键环节。以下是一些建议&#xff1a; 硬件配置选择&#xff1a; 内存&#xff08;RAM&#xff09;&#xff1a;建议至少使用32GB内存的服务器。为Kafk…

Web3Tools - 助记词生成

Web3Tools - 助记词生成工具 本文介绍了一个简单的助记词生成工具&#xff0c;使用 React 和 Material-UI 构建。用户可以选择助记词的语言和长度&#xff0c;然后生成随机的助记词并显示在页面上 功能介绍 选择语言和长度&#xff1a; 用户可以在下拉菜单中选择助记词的语言&…