打包您的软件

Dockerfile

这一切都始于 Dockerfile。

Docker 通过读取 Dockerfile 中的指令来构建镜像。 Dockerfile 是一个文本文件,其中包含构建源代码的说明。 Dockerfile 指令语法由Dockerfile 参考中的规范参考定义 。

以下是最常见的指令类型:

操作说明描述
FROM <image>定义图像的基础。
RUN <command>在当前图像之上的新层中执行任何命令并提交结果。RUN还有一个用于运行命令的 shell 形式。
WORKDIR <directory>为Dockerfile 中跟随的任何RUNCMDENTRYPOINTCOPY和指令设置工作目录。ADD
COPY <src> <dest><src>从容器的文件系统中复制新文件或目录并将其添加到路径 处<dest>
CMD <command>允许您定义基于此映像启动容器后运行的默认程序。每个 Dockerfile 只有一个CMDCMD当存在多个时,仅考虑最后一个实例。

Dockerfile 是映像构建的重要输入,可以根据您的独特配置促进自动化的多层映像构建。 Dockerfile 可以从简单开始,然后根据您的需求进行扩展,以支持更复杂的场景。

文件名

Dockerfile 使用的默认文件名是Dockerfile,不带文件扩展名。使用默认名称允许您运行docker build命令而无需指定其他命令标志。

某些项目可能需要不同的 Dockerfile 来实现特定目的。一个常见的约定是命名这些<something>.Dockerfile。您可以使用命令--file的标志指定 Dockerfile 文件名docker build。请参阅 docker buildCLI 参考 以了解该--file标志。

笔记

Dockerfile我们建议对项目的主 Dockerfile使用默认值 ( )。

Docker 镜像

Docker 镜像由层组成。每一层都是 Dockerfile 中构建指令的结果。层按顺序堆叠,每个层都是一个增量,表示应用于前一层的更改。

例子

以下是使用 Docker 构建应用程序的典型工作流程。

以下示例代码显示了一个使用 Flask 框架用 Python 编写的小型“Hello World”应用程序。

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

为了在不使用 Docker Build 的情况下发布和部署此应用程序,您需要确保:

  • 所需的运行时依赖项已安装在服务器上
  • Python 代码被上传到服务器的文件系统
  • 服务器使用必要的参数启动您的应用程序

以下 Dockerfile 创建一个容器映像,其中安装了所有依赖项并自动启动您的应用程序。

# syntax=docker/dockerfile:1
FROM ubuntu:22.04

# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip install flask==3.0.*

# install app
COPY hello.py /

# final configuration
ENV FLASK_APP=hello
EXPOSE 8000
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]

以下是该 Dockerfile 的详细信息:

Dockerfile 语法

添加到 Dockerfile 的第一行是 # syntax解析器指令。虽然可选,但该指令指示 Docker 构建器在解析 Dockerfile 时使用什么语法,并允许启用BuildKit的较旧 Docker 版本在开始构建之前 使用特定的 Dockerfile 前端。解析器指令 必须出现在 Dockerfile 中的任何其他注释、空格或 Dockerfile 指令之前,并且应该位于 Dockerfile 中的第一行。

# syntax=docker/dockerfile:1

提示

我们建议使用docker/dockerfile:1,它始终指向版本 1 语法的最新版本。 BuildKit 在构建之前自动检查语法更新,确保您使用的是最新版本。

基础镜像

语法指令后面的行定义要使用的基本映像:

FROM ubuntu:22.04

FROM指令将您的基础映像设置为 Ubuntu 22.04 版本。以下所有指令均在此基础映像中执行:Ubuntu 环境。符号ubuntu:22.04,遵循name:tagDocker 镜像的命名标准。当您构建图像时,您可以使用此符号来命名您的图像。您可以在项目中利用许多公共映像,方法是使用 DockerfileFROM指令将它们导入到构建步骤中。

Docker Hub 包含大量可用于此目的的官方映像。

环境设置

以下行在基础映像内执行构建命令。

# install app dependencies
RUN apt-get update && apt-get install -y python3 python3-pip

RUN指令在 Ubuntu 中执行一个 shell,更新 APT 包索引并在容器中安装 Python 工具。

评论

注意该# install app dependencies线。这是一条评论。 Dockerfile 中的注释以符号开头#。随着您的 Dockerfile 的发展,注释可以帮助记录您的 Dockerfile 如何为该文件的任何未来读者和编辑者(包括未来的您)工作!

笔记

您可能已经注意到,注释使用与文件第一行的语法指令相同的符号来表示 。仅当模式与指令匹配并且出现在 Dockerfile 的开头时,该符号才被解释为指令。否则,它将被视为评论。

安装依赖项

第二条指令RUN安装flaskPython 应用程序所需的依赖项。

RUN pip install flask==3.0.*

此指令的先决条件是pip安装到构建容器中。第一个RUN命令 install pip,这确保我们可以使用该命令安装 Flask Web 框架。

复制文件

下一条指令使用该 COPY指令将文件从本地构建上下文复制 hello.py到图像的根目录中。

COPY hello.py /

构建 上下文是您可以在 Dockerfile 指令中访问的一组文件,例如COPYADD

执行完指令后COPY,该hello.py文件将被添加到构建容器的文件系统中。

设置环境变量

ENV如果您的应用程序使用环境变量,您可以使用指令在 Docker 构建中设置环境变量 。

ENV FLASK_APP=hello

这设置了我们稍后需要的 Linux 环境变量。本示例中使用的框架 Flask 使用此变量来启动应用程序。如果没有这个,Flask 将不知道在哪里可以找到我们的应用程序来运行它。

暴露端口

EXPOSE指令标志着我们的最终映像有一个正在侦听端口的服务8000

EXPOSE 8000

此说明不是必需的,但它是一个很好的实践,可以帮助工具和团队成员了解此应用程序正在做什么。

启动应用程序

最后, CMD指令设置当用户启动基于该镜像的容器时运行的命令。

CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]

此命令启动 Flask 开发服务器侦听端口上的所有地址8000。这里的示例使用“exec form”版本的CMD.也可以使用“shell 形式”:

CMD flask run --host 0.0.0.0 --port 8000

这两个版本之间存在细微的差异,例如它们如何捕获SIGTERM和等信号SIGKILL。有关这些差异的详细信息,请参阅 Shell 和 exec 形式

建筑

要使用上一节中的 Dockerfile 示例构建容器映像 ,请使用以下docker build命令:

$ docker build -t test:latest .

-t test:latest选项指定图像的名称和标签。

.命令末尾的 单点 ( ) 将构建上下文设置为当前目录。这意味着构建期望hello.py在调用命令的目录中找到 Dockerfile 和文件。如果这些文件不存在,则构建失败。

构建镜像后,您可以使用 来将应用程序作为容器运行 docker run,并指定镜像名称:

$ docker run -p 127.0.0.1:8000:8000 test:latest

这会将容器的端口 8000 发布到http://localhost:8000Docker 主机上。

其他资源

如果您对其他语言(例如 Go)的示例感兴趣,请查看指南部分中的特定语言指南。

有关构建的更多信息,包括高级用例和模式,请参阅使用 Docker 构建指南。