打包您的软件
Dockerfile
这一切都始于 Dockerfile。
Docker 通过读取 Dockerfile 中的指令来构建镜像。 Dockerfile 是一个文本文件,其中包含构建源代码的说明。 Dockerfile 指令语法由Dockerfile 参考中的规范参考定义 。
以下是最常见的指令类型:
操作说明 | 描述 |
---|---|
FROM <image> | 定义图像的基础。 |
RUN <command> | 在当前图像之上的新层中执行任何命令并提交结果。RUN 还有一个用于运行命令的 shell 形式。 |
WORKDIR <directory> | 为Dockerfile 中跟随的任何RUN 、CMD 、ENTRYPOINT 、COPY 和指令设置工作目录。ADD |
COPY <src> <dest> | <src> 从容器的文件系统中复制新文件或目录并将其添加到路径 处<dest> 。 |
CMD <command> | 允许您定义基于此映像启动容器后运行的默认程序。每个 Dockerfile 只有一个CMD ,CMD 当存在多个时,仅考虑最后一个实例。 |
Dockerfile 是映像构建的重要输入,可以根据您的独特配置促进自动化的多层映像构建。 Dockerfile 可以从简单开始,然后根据您的需求进行扩展,以支持更复杂的场景。
文件名
Dockerfile 使用的默认文件名是Dockerfile
,不带文件扩展名。使用默认名称允许您运行docker build
命令而无需指定其他命令标志。
某些项目可能需要不同的 Dockerfile 来实现特定目的。一个常见的约定是命名这些<something>.Dockerfile
。您可以使用命令--file
的标志指定 Dockerfile 文件名docker build
。请参阅
docker build
CLI 参考
以了解该--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:tag
Docker 镜像的命名标准。当您构建图像时,您可以使用此符号来命名您的图像。您可以在项目中利用许多公共映像,方法是使用 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
安装flask
Python 应用程序所需的依赖项。
RUN pip install flask==3.0.*
此指令的先决条件是pip
安装到构建容器中。第一个RUN
命令 install pip
,这确保我们可以使用该命令安装 Flask Web 框架。
复制文件
下一条指令使用该
COPY
指令将文件从本地构建上下文复制
hello.py
到图像的根目录中。
COPY hello.py /
构建
上下文是您可以在 Dockerfile 指令中访问的一组文件,例如COPY
和ADD
。
执行完指令后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:8000
Docker 主机上。
其他资源
如果您对其他语言(例如 Go)的示例感兴趣,请查看指南部分中的特定语言指南。
有关构建的更多信息,包括高级用例和模式,请参阅使用 Docker 构建指南。