运维
PythonJava前端数据库
Docker
Docker
  • Docker简介
  • 基本概念
    • 镜像
    • 容器
    • 仓库
  • 安装
  • 使用镜像
    • 获取镜像
    • 列出镜像
    • 删除镜像
    • 导入和导出
  • Dockerfile
    • 构建镜像
    • 多阶段构建
    • 构建多种系统架构支持的镜像
    • Dockerfile 命令介绍
      • COPY 复制文件
      • ADD 更高级的复制
      • CMD 容器启动命令
      • ENTPYPOINT 入口点
      • ENV 设置环境变量
      • ARG 构建参数
      • VOLUME 匿名卷
      • USER 指定当前用户
      • EXPOSE 暴露端口
      • WORKDIR 工作目录
      • SHELL 指令
      • LABEL 为镜像添加源数据
      • ONBUILD 为他人作嫁衣裳
  • 数据管理
    • 数据卷
    • 挂载主机目录
  • 操作容器
    • 启动、停止和删除
    • 进入容器
    • 导入和导出
    • 重启策略
  • 网络配置
    • 基本网络配置
    • 高级网络配置
  • Docker Buildx
    • 使用buildx构建镜像
    • 使用buildx构建多种系统架构镜像
  • Docker Compose
    • 简介
    • 简单使用
    • 多个配置文件
    • Compose网络配置
    • 控制启动服务启动顺序
    • 命令说明
  • Kubernetes
由 GitBook 提供支持
在本页

这有帮助吗?

  1. Dockerfile
  2. Dockerfile 命令介绍

CMD 容器启动命令

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/ps-release。这就是用cat /etc/os-release 命令替换了默认的 /bin/bash 命令。

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

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

CMD echo $HOME

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

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

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

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

一些初学者将CMD写为:

CMD service nginx start

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

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

CMD ["nginx", "-g", "daemon off;"]
上一页ADD 更高级的复制下一页ENTPYPOINT 入口点

最后更新于1年前

这有帮助吗?