CMD 指令的格式和 RUN 相似,也是两种格式:

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
  • 参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。

之前介绍容器的时候曾经说过,Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。

在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,ubuntu 镜像默认的 CMD/bin/bash,如果我们直接 docker run -it ubuntu 的话,会直接进入 bash。我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release。这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息。

在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",而不要使用单引号。

如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:

CMD echo $HOME

在实际执行中,会将其变更为:

CMD [ "sh", "-c", "echo $HOME" ]

这就是为什么我们可以使用环境变量的原因,因为这些环境变量会被 shell 进行解析处理。

提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。

Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd 去启动后台服务,容器内没有后台服务的概念。

一些初学者将 CMD 写为:

CMD service nginx start

然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。

对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。

而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为 CMD [ "sh", "-c", "service nginx start"],因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。

正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:

CMD ["nginx", "-g", "daemon off;"]

docker的cmd命令详解-前后台理解的更多相关文章

  1. cmd命令详解

    这几天用了一下Windows系统的“黑框”,即win+R键,发现有些命令都忘了,还得查,就总结了一下: cmd命令 CMD命令:开始->运行->键入cmd或command(在命令行里可以看 ...

  2. Docker:Dockerfile命令详解

    1.FROM 功能为指定基础镜像,并且必须是第一条指令. 如果不以任何镜像为基础,那么写法为:FROM scratch. 同时意味着接下来所写的指令将作为镜像的第一层开始 语法: FROM <i ...

  3. Docker 学习之命令详解

    1. docker version docker version 显示 Docker 版本信息. 2. docker info docker info 显示 Docker 系统信息,包括镜像和容器数. ...

  4. Windows学习总结(10)——Windows系统中常用的CMD命令详解

    1.ping命令 ping是电脑网络故障诊断中的常用的命令,它的作用是用来检查网络是否通畅或者网络连接速度.我们来看一下PING命令的具体表述. 日常的诊断过程中我们最常用到的就是诊断连接是否通畅. ...

  5. [转帖]Docker学习之Dockerfile命令详解

    Docker学习之Dockerfile命令详解 https://it.baiked.com/system/docker/2436.html 图挺好的 前言 之前,制作镜像的伪姿势搭建已经见过了,今天介 ...

  6. Docker命令详解

    Docker命令详解   最近学习Docker,将docker所有命令实验了一番,特整理如下: # docker --help Usage: docker [OPTIONS] COMMAND [arg ...

  7. Docker常用命令详解

    docker ps 查看当前正在运行的容器 docker ps -a 查看所有容器的状态 docker start/stop id/name 启动/停止某个容器 docker attach id 进入 ...

  8. 【Devops】【docker】【CI/CD】关于jenkins构建成功后一步,执行的shell命令详解+jenkins容器运行宿主机shell命令的实现方法

    1.展示这段shell命令 +详解 #================================================================================= ...

  9. Dockerfile 命令详解及最佳实践

    Dockerfile 命令详解 FROM 指定基础镜像(必选) 所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制.就像我们之前运行了一个 nginx 镜像的容器,再进行修改一样,基础镜像是必须指 ...

随机推荐

  1. 千位分隔符在web开发中的作用

    有千位分隔符会被认为是数字,否则在移动端会被直接识别成手机号 在开发实战中主流实现方式是添加meta标签 <meta name="format-detection" cont ...

  2. pyinstaller打包一些三方库后,报资源不存在

    在目录site-packages\PyInstaller\hooks下新建对应文件hook-对应三方库名字.py,如hook-ngender.py 编辑hook-ngender.py: from Py ...

  3. C++多文件源程序

    一.多文件结构的源代码组织 一个C++程序开发工程(project)可以包含多个源程序文件,一个源程序文件(.cpp)可以包含多个函数.一个函数只能集中放在一个源程序文件中,不能将其定义代码拆开存放在 ...

  4. Solution -「CF1373G」Pawns

    小清新线段树题(( 每个位置的边只能向靠右的三个方向走,最后要走到一条基准线上.即对于一个点 \((x, y)\),它最后应该落在 \((k, y + |k - x|)\). 士兵可以一个一个进行移动 ...

  5. TFRecord的Shuffle、划分和读取

    对数据集的shuffle处理需要设置相应的buffer_size参数,相当于需要将相应数目的样本读入内存,且这部分内存会在训练过程中一直保持占用.完全的shuffle需要将整个数据集读入内存,这在大规 ...

  6. 可以级联的以太网远程IO模块的优点与适用场景

    可以级联的以太网远程IO模块的优点与具体的适用场景 对于数据采集控制点是按照线性分布的场景,比如智慧园区的路灯.桥梁.路灯.数字化工厂.停车场车位监测.智慧停车场.智能停车架.楼宇自动控制系统等场景, ...

  7. RabbitMQ延迟消息:死信队列 | 延迟插件 | 二合一用法+踩坑手记+最佳使用心得

    前言 前段时间写过一篇: # RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得 很多人加了我好友,说很喜欢这篇文章,也问了我一些问题. 因为最近工作比较忙, ...

  8. 使用 Java 操作 Redis

    Jedis 1. 概述 Jedis 是一款使用 Java 操作 Redis 的工具,有点类似于 JDBC 2. 引入依赖 <dependency> <groupId>redis ...

  9. .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...

  10. rcu使用遇到问题汇总

    1.3.10内核,在项目中遇到一种情况,我们根据sk指针hash到一个cpu上,然后访问该cpu对应分配的一个数据区. 然后系统会偶尔crash掉,crash掉有两种情况,一种是cred的rcu回收时 ...