迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 操作系统 > Docker >

Docker 中 CMD 和 ENTRYPOINT 的区别

作者:迹忆客 最近更新:2023/03/22 浏览次数:

在不同环境中管理软件和依赖项时,Docker 容器已成为标准。在使用实际应用程序时,你需要在构建应用程序容器映像之前创建一个 docker 文件。

docker 文件只是一个只读文本文档,其中包含一组在组装镜像时将调用的指令。这些命令包括 RUNCMDENTRYPOINT

在本文中,我们将讨论这些命令的用法。大多数可能处于学习 docker 初始阶段的开发人员倾向于交替使用这些命令,这可能会给你带来一些问题。

Docker 中的 CMD 命令

此命令指定执行 docker RUN 命令时执行的指令。但是,这需要在不指定任何参数的情况下执行 docker RUN 命令。

指定参数时,此命令将被覆盖。另一方面,如果没有指定命令行参数,则执行 CMD 命令。

CMD 命令对于你的 docker 容器正常运行不是必需的,因为 ECHO 命令可以在运行时用于相同目的。但是,当每次容器启动时运行可执行文件时,CMD 命令会很方便。

为了演示如何使用 CMD 命令在运行时运行可执行文件,我们将创建一个简单的 docker 容器,其中包含一个打印出消息的简单 Flask 程序。请注意,这可以用任何语言复制,不一定是 Python。

我们将从创建我们的主应用程序开始,它应该如下所示那样简单。

from flask import Flask

app = Flask(__name__)


def hello():
    print("Hello, this is a simple Flask application")

hello()

在同一个文件夹中,我们将使用命令 touch Dockerfile 创建我们的 Dockerfile。

Dockerfile 只指定了基础镜像、工作目录和应该安装的包。

在最后一行,你应该注意 CMD 命令。在这种情况下,我们使用 CMD 命令在容器启动时执行 app.py 文件。

#  base image
FROM python

# Set your working directory
WORKDIR /var/www/

# Copy the necessary files
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
CMD python3 app.py

requirements.txt 应如下所示。

click==8.0.4
Flask==2.0.3
gunicorn==20.1.0
itsdangerous==2.1.0
Jinja2==3.0.3
MarkupSafe==2.1.0
Werkzeug==2.0.3

现在我们已经准备好了一切,我们现在可以继续构建 docker 镜像了。在此之前,我们需要确保我们位于存储程序的同一文件夹中。

在我们的例子中,我们将在构建映像之前将 cd 放入 my-app 文件夹,如下所示。

~/my-app$ docker build -t isaactonyloi_image .

输出:

 => [internal] load build context                                                                                                          0.9s
 => => transferring context: 320B                                                                                                          0.1s
 => [2/5] WORKDIR /var/www/                                                                                                                5.1s
 => [3/5] COPY ./app.py /var/www/app.py                                                                                                    3.2s
 => [4/5] COPY ./requirements.txt /var/www/requirements.txt                                                                                3.2s
 => [5/5] RUN pip install -r /var/www/requirements.txt                                                                                    53.9s
 => exporting to image                                                                                                                     6.9s
 => => exporting layers                                                                                                                    5.8s
 => => writing image sha256:5847e4777754d9d576accd929076bfbee633ca71f049ebe1af6e9bae161f3e96                                               0.1s
 => => naming to docker.io/library/isaactonyloi_image                                                                                      0.2s
isaac@DESKTOP-HV44HT6:~/my-app$

我们已经成功地基于早期的 docker 文件构建了我们的镜像。我们可以在下面验证。

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
isaactonyloi_image   latest    5847e4777754   7 minutes ago   929MB

我们终于可以使用基于此镜像的 docker run 命令创建我们的 docker 容器。另外,请注意,我们将在不传递任何参数来执行 CMD 命令的情况下执行此操作。

~/my-app$ docker run isaactonyloi_image
Hello, this is a simple Flask application

除此之外,CMD 命令还允许我们创建可以在运行时轻松覆盖的参数。

我们在下面的示例中对 CMD 命令进行了更改。其他文件保持不变,我们已经重建了一个新镜像。

# base image
FROM python

# Set your working directory
WORKDIR /var/www/

# Copy the necessary filesls
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt

# Install the necessary packages
RUN pip install -r /var/www/requirements.txt

# Run the app
CMD ["echo", "Hello, Developer"]

这是我们根据对 Dockerfile 的更改重建的新映像。

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
new_image            latest    73f323be0d2f   25 minutes ago   929MB

在不传递任何参数的情况下再次创建新的 docker 容器时,我们应该在 CMD 命令下收到消息。

isaac@DESKTOP-HV44HT6:~/my-app$ docker run new_image
Hello, Developer

但是,当我们在运行时传递参数时,CMD 命令将自动被覆盖,并且新参数应该优先。因此,它为我们提供了在运行时添加新参数的灵活性,如下所示。

~/my-app$ docker run new_image hostname
da0a832888cb

上面的输出显示 CMD 命令没有被新的主机名参数执行和覆盖。

Docker 中的 ENTRYPOINT 命令

docker ENTRYPOINT 命令与 CMD 命令有相似之处,但并不完全相同。

当使用 CMD 命令时,我们可以通过在运行时传递参数轻松地覆盖它,但 ENTRYPOINT 命令并非如此。

因此,ENTRYPOINT 可用于在运行时不覆盖入口点指令。

如下所示,我们可以通过简单地将 Dockerfile 中的 CMD 命令替换为 ENTRYPOINT 命令来探索此命令的工作原理。我们将根据对 docker 文件的更改构建一个新镜像。

isaac@DESKTOP-HV44HT6:~/my-app$ docker build -t tonyloi_newimage .
[+] Building 42.7s (10/10) FINISHED

输出:

 => [internal] load build definition from Dockerfile                                                                                                                          2.0s
 => => transferring dockerfile: 365B                                                                                                                                          0.7s
 => [internal] load .dockerignore                                                                                                                                             1.6s
 => => transferring context: 2B                                                                                                                                               0.4s
 => [internal] load metadata for docker.io/library/python:latest                                                                                                             35.4s
 => [1/5] FROM docker.io/library/python@sha256:c90e15c86e2ebe71244a2a51bc7f094554422c159ce309a6faadb6debd5a6df0                                                               0.3s
 => [internal] load build context                                                                                                                                             1.2s
 => => transferring context: 63B                                                                                                                                              0.1s
 => CACHED [2/5] WORKDIR /var/www/                                                                                                                                            0.0s
 => CACHED [3/5] COPY ./app.py /var/www/app.py                                                                                                                                0.0s
 => CACHED [4/5] COPY ./requirements.txt /var/www/requirements.txt                                                                                                            0.0s
 => CACHED [5/5] RUN pip install -r /var/www/requirements.txt                                                                                                                 0.0s
 => exporting to image                                                                                                                                                        2.1s
 => => exporting layers                                                                                                                                                       0.0s
 => => writing image sha256:15fb8e4e3ff58ed529b11342bba75b029fd4323beb24aac70ca36b178d04cb34                                                                                  0.2s
 => => naming to docker.io/library/tonyloi_newimage                                                                                                                           0.1s
isaac@DESKTOP-HV44HT6:~/my-app$

此输出证明我们已成功构建了新映像。现在我们可以基于这个镜像创建一个新的 docker 容器。

你可以选择使用镜像名称或镜像 ID 创建容器,这两者都可以使用 docker images 命令访问。这也将显示我们之前创建的镜像。

~/my-app$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
tonyloi_newimage     latest    15fb8e4e3ff5   48 minutes ago   929MB
new_image            latest    73f323be0d2f   48 minutes ago   929MB
isaactonyloi_image   latest    5847e4777754   48 minutes ago   929MB

如果我们在不添加任何参数的情况下构建 docker 容器,我们应该得到如下输出。

isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage
Hello, Developer

如果我们在基于此镜像创建另一个容器时尝试传递参数,你会注意到,与 CMD 命令的情况不同,这些新参数不会覆盖 ENTRYPOINT 命令。

我们可以在下面验证这一点。

isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage Welcome to ADC
Hello, Developer Welcome to ADC

结论

我们可以说这两个命令非常相似; 但是,它们的区别在于 CMD 命令可以在运行时被覆盖,而 ENTRYPOINT 命令不能。

此外,某些情况可能需要同时使用这两个命令。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 Linux 中托管 Docker Internal

发布时间:2023/04/18 浏览次数:139 分类:Docker

Docker 允许开发人员通过将应用程序包装在称为容器的标准化单元中来高效地构建、测试和部署应用程序。 在使用 Docker 容器时,您可能会遇到需要将容器与主机连接的场景。

在 Docker 中设置工作目录

发布时间:2023/04/18 浏览次数:82 分类:Docker

在 Docker 中,我们可以通过编辑 Dockerfile 并添加密钥 WORKDIR 来设置我们的工作目录。本文将讨论在 Docker 中更改我们当前和默认的工作目录。

在 Docker 容器中公开多个端口

发布时间:2023/04/18 浏览次数:143 分类:Docker

Docker 容器使用端口来实现万维网上不同设备之间的通信。 在本篇文章中,我们将学习如何使用 Nginx 应用程序在 Docker 容器中公开多个端口。

将用户添加到 Docker 容器

发布时间:2023/04/18 浏览次数:187 分类:Docker

在本文中,我们将学习如何通过实现返回产品数组的 Express 应用程序将用户添加到 Docker 容器。

使用 Docker 网络主机命令

发布时间:2023/04/18 浏览次数:112 分类:Docker

在本文中,我们将学习如何使用 --network 命令将容器添加到主机网络。 如果我们不使用此命令指定网络,我们还将了解如何将容器添加到默认网络。

清除 Docker 容器日志

发布时间:2023/04/18 浏览次数:181 分类:Docker

本文介绍了我们可以用来清除 docker 容器中日志的不同方法。日志是应用程序在特定事件或状态发生时记录的信息,它们帮助我们监控应用程序并采取必要的措施。

Docker 中的守护进程日志位置

发布时间:2023/04/18 浏览次数:175 分类:Docker

本文将讨论守护进程事件以及我们通常可以在哪里找到每个操作系统 (OS) 的守护进程日志。

Dockerfile 中 COPY 和 ADD 命令的区别

发布时间:2023/04/18 浏览次数:158 分类:Docker

在 Dockerfile 中,我们可以使用 COPY 或 ADD 命令复制这些文件。 这些命令在功能上是相同的; 但是,存在一些差异。本文介绍了 Dockerfile 中 COPY 和 ADD 命令之间的区别。

Docker 中的 --rm 标志

发布时间:2023/04/18 浏览次数:77 分类:Docker

本文介绍如何在 docker 中使用 --rm 命令。 此外,它还提供了使用命令的优势。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便