RUN vs CMD vs ENTRYPOINT - 每天5分钟玩转 Docker 容器技术(17)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似很容易混淆。本节将通过实践详细讨论它们的区别。

简单的说

  1. RUN 执行命令并创建新的镜像层RUN 经常用于安装软件包。

  2. CMD 设置容器启动后默认执行的命令及其参数但 CMD 能够被 docker run 后面跟的命令行参数替换。

  3. ENTRYPOINT 配置容器启动时运行的命令。

下面我们详细分析。

Shell 和 Exec 格式

我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令Shell 格式和 Exec 格式二者在使用上有细微的区别。

Shell 格式

<instruction> <command>


例如

RUN apt-get install python3  

CMD echo "Hello world"  

ENTRYPOINT echo "Hello world" 


当指令执行时shell 格式底层会调用 /bin/sh -c <command>
 

例如下面的 Dockerfile 片段

ENV name Cloud Man  

ENTRYPOINT echo "Hello, $name" 


执行 docker run <image> 将输出

Hello, Cloud Man

 

注意环境变量 name 已经被值 Cloud Man 替换。

下面来看 Exec 格式。

Exec 格式

<instruction> ["executable", "param1", "param2", ...]

 

例如

RUN ["apt-get", "install", "python3"]  

CMD ["/bin/echo", "Hello world"]  

ENTRYPOINT ["/bin/echo", "Hello world"]

 

当指令执行时会直接调用 <command>不会被 shell 解析。
例如下面的 Dockerfile 片段

ENV name Cloud Man  

ENTRYPOINT ["/bin/echo", "Hello, $name"]

 

运行容器将输出

Hello, $name

 

注意环境变量“name”没有被替换。
如果希望使用环境变量照如下修改

ENV name Cloud Man  

ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

 

运行容器将输出

Hello, Cloud Man

 

CMD 和 ENTRYPOINT 推荐使用 Exec 格式因为指令可读性更强更容易理解。RUN 则两种格式都可以。

RUN

RUN 指令通常用于安装应用和软件包。

RUN 在当前镜像的顶部执行命令并通过创建新的镜像层。Dockerfile 中常常包含多个 RUN 指令。

RUN 有两种格式

  1. Shell 格式RUN

  2. Exec 格式RUN ["executable", "param1", "param2"]

下面是使用 RUN 安装多个包的例子

RUN apt-get update && apt-get install -y \  

 bzr \

 cvs \

 git \

 mercurial \

 subversion

 

注意apt-get update 和 apt-get install 被放在一个 RUN 指令中执行这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行则会使用 apt-get update 创建的镜像层而这一层可能是很久以前缓存的。

CMD

CMD 指令允许用户指定容器的默认执行的命令。

此命令会在容器启动且 docker run 没有指定其他命令时运行。

  1. 如果 docker run 指定了其他命令CMD 指定的默认命令将被忽略。

  2. 如果 Dockerfile 中有多个 CMD 指令只有最后一个 CMD 有效。

CMD 有三种格式

  1. Exec 格式CMD ["executable","param1","param2"]
    这是 CMD 的推荐格式。

  2. CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数此时 ENTRYPOINT 必须使用 Exec 格式。

  3. Shell 格式CMD command param1 param2

Exec 和 Shell 格式前面已经介绍过了。
第二种格式 CMD ["param1","param2"] 要与 Exec 格式 的 ENTRYPOINT 指令配合使用其用途是为 ENTRYPOINT 设置默认的参数。我们将在后面讨论 ENTRYPOINT 时举例说明。

下面看看 CMD 是如何工作的。Dockerfile 片段如下

CMD echo "Hello world"

 

运行容器 docker run -it [image] 将输出

Hello world

 

但当后面加上一个命令比如 docker run -it [image] /bin/bashCMD 会被忽略掉命令 bash 将被执行

root@10a32dc7d3d3:/#

 

ENTRYPOINT

ENTRYPOINT 指令可让容器以应用程序或者服务的形式运行。

ENTRYPOINT 看上去与 CMD 很像它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 不会被忽略一定会被执行即使运行 docker run 时指定了其他命令。

ENTRYPOINT 有两种格式

  1. Exec 格式ENTRYPOINT ["executable", "param1", "param2"] 这是 ENTRYPOINT 的推荐格式。

  2. Shell 格式ENTRYPOINT command param1 param2

在为 ENTRYPOINT 选择格式时必须小心因为这两种格式的效果差别很大。

Exec 格式

ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数同时可通过 CMD 提供额外的参数。

ENTRYPOINT 中的参数始终会被使用而 CMD 的额外参数可以在容器启动时动态替换掉。

比如下面的 Dockerfile 片段

ENTRYPOINT ["/bin/echo", "Hello"]  

CMD ["world"]

 

当容器通过 docker run -it [image] 启动时输出为

Hello world

 

而如果通过 docker run -it [image] CloudMan 启动则输出为

Hello CloudMan

 

Shell 格式

ENTRYPOINT 的 Shell 格式会忽略任何 CMD 或 docker run 提供的参数。

最佳实践

  1. 使用 RUN 指令安装应用和软件包构建镜像。

  2. 如果 Docker 镜像的用途是运行应用程序或服务比如运行一个 MySQL应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数同时可利用 docker run 命令行替换默认参数。

  3. 如果想为容器设置默认的启动命令可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

到这里我们已经具备编写 Dockerfile 的能力了。如果大家还觉得没把握推荐一个快速掌握 Dockerfile 的方法去 Docker Hub 上参考那些官方镜像的 Dockerfile

好了我们已经学习完如何创建自己的 image下一节讨论如何分发 image。

二维码+指纹.png



本文转自CloudMan6 51CTO博客,原文链接:http://blog.51cto.com/cloudman/1927363

相关文章
|
2月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
570 108
|
4月前
|
存储 容器
46.[HarmonyOS NEXT RelativeContainer案例三] 打造自适应容器:内容驱动的智能尺寸调整技术
在HarmonyOS NEXT的UI开发中,创建能够根据内容自动调整尺寸的容器是实现灵活布局的关键。RelativeContainer结合自适应尺寸设置,可以实现内容驱动的智能尺寸调整,使UI更加灵活且易于维护。本教程将详细讲解如何创建自适应尺寸的RelativeContainer,帮助你掌握这一实用技术。
160 5
|
18天前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
208 2
|
2月前
|
运维 数据可视化 C++
2025 热门的 Web 化容器部署工具对比:Portainer VS Websoft9
2025年热门Web化容器部署工具对比:Portainer与Websoft9。Portainer以轻量可视化管理见长,适合技术团队运维;Websoft9则提供一站式应用部署与容器管理,内置丰富开源模板,降低中小企业部署门槛。两者各有优势,助力企业提升容器化效率。
283 1
2025 热门的 Web 化容器部署工具对比:Portainer VS Websoft9
|
6月前
|
存储 安全 C++
Odoo 安装方式选择:源码安装 vs Docker
Odoo部署常采用源码编译或Docker容器化,但分别面临依赖复杂、版本风险和服务化难题,以及镜像臃肿和扩展受限的问题。Websoft9提出混合方案,融合两者优势:通过智能环境适配、三阶段部署流程(环境预检、混合模式选择、持久化配置)及声明式YAML配置,实现高效、灵活的双模运行时。此方案显著降低依赖冲突解决时间(从83分钟至0),生产环境构建耗时缩短至8分钟,并达100% CVE漏洞修复率,适合ERP定制开发与规模化部署的企业需求。
|
4月前
|
Docker 容器
Docker run命令-p参数详解
本文介绍Docker端口映射的基础用法。通过`docker run -p &lt;宿主机端口&gt;:&lt;容器端口&gt;`实现端口映射,例如`-p 5000:80`将宿主机5000端口映射到容器80端口,外部访问宿主机5000端口时流量会转发至容器内部的80端口。示例命令中,`-d`用于后台运行,`--restart=always`确保容器自动重启,`--name`指定容器名称。部署完成后可通过`http://服务器IP地址:5000`验证服务是否正常运行。
|
2月前
|
Kubernetes Cloud Native 持续交付
Docker:轻量级容器化技术解析
Docker:轻量级容器化技术解析
|
2月前
|
运维 测试技术 Docker
Docker:轻量级容器化技术革命
Docker:轻量级容器化技术革命
|
6月前
|
弹性计算 Java Maven
从代码到容器:Cloud Native Buildpacks技术解析
Cloud Native Buildpacks(CNB)是一种标准化、云原生的容器镜像构建系统,旨在消除手动编写Dockerfile,提供可重复、安全且高效的构建流程。它通过分层策略生成符合OCI标准的镜像,实现应用与基础镜像解耦,并自动化依赖管理和更新。阿里云应用管理支持通过CNB技术一键部署应用至ECS,简化构建和运行流程。
|
7月前
|
Kubernetes Docker 容器
Kubernetes与Docker参数对照:理解Pod中的command、args与Dockerfile中的CMD、ENTRYPOINT。
需要明确的是,理解这些都需要对Docker和Kubernetes有一定深度的理解,才能把握二者的区别和联系。虽然它们都是容器技术的二个重要组成部分,但各有其特性和适用场景,理解它们的本质和工作方式,才能更好的使用这些工具,将各自的优点整合到生产环境中,实现软件的快速开发和部署。
244 25