如何使用 docker compose build 命令构建服务

DockerDockerBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何高效使用 docker compose build 命令来构建 Docker Compose 文件中定义的服务。首先,你需要准备一个简单的 Docker Compose 文件来定义一个多容器应用。

完成设置后,你将使用 docker compose build 命令构建这些服务。接着,你将探索在修改对应 Dockerfile 后如何重新构建服务。最后,你将学习如何使用构建参数(build arguments)来构建服务,以及如何利用 --no-cache 选项进行全新构建。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-555073{{"如何使用 docker compose build 命令构建服务"}} docker/pull -.-> lab-555073{{"如何使用 docker compose build 命令构建服务"}} docker/images -.-> lab-555073{{"如何使用 docker compose build 命令构建服务"}} docker/build -.-> lab-555073{{"如何使用 docker compose build 命令构建服务"}} end

准备一个简单的 Docker Compose 文件

在本步骤中,你将学习如何创建一个基础的 Docker Compose 文件来定义和管理多容器 Docker 应用。Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过 Compose,你可以使用 YAML 文件来配置应用服务,然后只需一条命令就能根据配置创建并启动所有服务。

首先,我们需要安装 Docker Compose。由于 LabEx 环境中没有预装该工具,我们需要下载二进制文件。

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

该命令会从 GitHub 官方发布页面下载 Docker Compose 二进制文件,并保存到 /usr/local/bin/docker-compose。其中 $(uname -s)$(uname -m) 会自动检测你的操作系统和架构以下载正确的二进制文件。

接下来,我们需要为下载的二进制文件添加可执行权限。

sudo chmod +x /usr/local/bin/docker-compose

这条命令使得 docker-compose 命令可以执行。

现在,让我们通过检查版本来验证安装是否成功。

docker-compose --version

你应该会看到类似 Docker Compose version v2.20.2 的输出,确认 Docker Compose 已正确安装。

现在,让我们创建一个简单的 Docker Compose 文件。我们将定义一个使用 nginx 镜像的服务。

首先进入项目目录:

cd ~/project

使用 nano 编辑器创建一个名为 docker-compose.yml 的新文件:

nano docker-compose.yml

在文件中添加以下内容:

version: "3.8"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

让我们分解这个文件的内容:

  • version: '3.8' 指定了 Docker Compose 文件格式版本
  • services: 定义了组成应用的各个服务
  • web: 是我们的服务名称,你可以使用任意名称
  • image: nginx:latest 指定了该服务使用的 Docker 镜像,这里我们使用官方 Nginx 镜像的最新版本
  • ports: 映射主机和容器之间的端口,"80:80" 将主机的 80 端口映射到容器的 80 端口

Ctrl + X,然后按 YEnter 保存文件。

现在,让我们拉取 docker-compose.yml 文件中指定的 nginx:latest 镜像。虽然 Docker Compose 会在运行 docker-compose up 时自动拉取镜像,但在实验环境中预先显式拉取镜像是个好习惯,可以确保镜像可用。

docker pull nginx:latest

这条命令会从 Docker Hub 下载 nginx:latest 镜像,你将看到显示下载进度的输出。

使用 docker compose build 构建服务

在前一步骤中,我们创建了一个简单的 docker-compose.yml 文件,它使用了现有的 Docker 镜像(nginx)。Docker Compose 也可以从 Dockerfile 构建镜像,这在需要自定义镜像或为你的应用构建镜像时非常有用。

在本步骤中,我们将修改 docker-compose.yml 文件,使其从 Dockerfile 构建镜像,而不是使用预构建的镜像。

首先,在 ~/project 目录下创建一个简单的 Dockerfile

nano ~/project/Dockerfile

Dockerfile 添加以下内容:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "Hello, Docker Compose!"]

让我们解释这个 Dockerfile

  • FROM ubuntu:latest 指定了新镜像的基础镜像,我们使用官方 Ubuntu 镜像的最新版本
  • RUN apt-get update && apt-get install -y cowsay 更新软件包列表并安装 cowsay 包。cowsay 命令会在牛形图案的气泡中显示消息
  • CMD ["cowsay", "Hello, Docker Compose!"] 设置从该镜像启动容器时执行的默认命令

Ctrl + X,然后按 YEnter 保存 Dockerfile

现在,我们修改 docker-compose.yml 文件来使用这个 Dockerfile。打开文件进行编辑:

nano ~/project/docker-compose.yml

将内容修改为以下内容:

version: "3.8"
services:
  cow:
    build: .

在这个更新后的 docker-compose.yml 中:

  • 我们将服务名称从 web 改为 cow,以更好地反映其用途
  • build: . 替换了 image: 指令。build: . 指令告诉 Docker Compose 使用当前目录(.)中的 Dockerfile 构建该服务的镜像

Ctrl + X,然后按 YEnter 保存 docker-compose.yml 文件。

现在,我们可以使用 docker-compose build 命令来构建 cow 服务的镜像。确保你位于 ~/project 目录下:

cd ~/project
docker-compose build

该命令会读取 docker-compose.yml 文件,找到 cow 服务,并根据当前目录中的 Dockerfile 构建镜像。你将看到显示构建步骤的输出,包括下载 Ubuntu 基础镜像、更新软件包和安装 cowsay

构建完成后,你可以通过列出本地 Docker 镜像来验证镜像是否已创建:

docker images

你应该会看到一个名称类似 project_cow(Docker Compose 会根据目录名和服务名自动命名镜像)且标签为 latest 的镜像。

修改 Dockerfile 后重新构建服务

在前一步骤中,我们使用 Dockerfiledocker-compose build 构建了一个 Docker 镜像。如果我们修改了 Dockerfile 会发生什么?Docker 使用缓存机制来加速构建过程。如果 Dockerfile 中的某一层没有变化,Docker 会使用缓存版本而不是重新构建。但是,如果某一层或后续层发生变化,Docker 将会重新构建这些层。

在本步骤中,我们将修改 Dockerfile 并重新构建镜像,观察 Docker 如何处理这些变更。

首先,我们修改 Dockerfile 来改变 cowsay 显示的消息。打开 Dockerfile 进行编辑:

nano ~/project/Dockerfile

CMD 行修改为以下内容:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "Hello again, Docker Compose!"]

我们将消息从 "Hello, Docker Compose!" 改为 "Hello again, Docker Compose!"。

Ctrl + X,然后按 YEnter 保存 Dockerfile

现在,我们再次使用 docker-compose build 命令重新构建镜像。确保你位于 ~/project 目录下:

cd ~/project
docker-compose build

观察构建过程的输出。你会注意到前两个步骤(FROM ubuntu:latestRUN apt-get update && apt-get install -y cowsay)很可能会使用之前构建的缓存层。但是最后一个步骤(CMD ["cowsay", "Hello again, Docker Compose!"])将会被重新构建,因为我们修改了这一行内容。

构建完成后,你可以通过列出本地 Docker 镜像来验证镜像是否已更新:

docker images

project_cow 镜像现在应该反映了 Dockerfile 中的修改。虽然镜像 ID 可能改变,但名称和标签保持不变。

为了进一步确认变更,我们可以从这个新构建的镜像运行一个容器并查看输出:

docker run project_cow

你应该会看到 cowsay 输出更新后的消息:"Hello again, Docker Compose!"。

使用构建参数和无缓存方式构建服务

在本步骤中,我们将探索 Docker Compose 的两个高级构建选项:使用构建参数和无缓存构建。

构建参数允许你向 Docker 构建过程传递变量。这在需要根据不同环境或配置自定义构建时非常有用,而无需修改 Dockerfile 本身。

首先,我们修改 Dockerfile 以接受构建参数。打开 Dockerfile 进行编辑:

nano ~/project/Dockerfile

将内容修改为以下内容:

FROM ubuntu:latest
ARG MESSAGE="Hello from build argument!"
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "$MESSAGE"]

我们添加了 ARG MESSAGE 指令来定义一个名为 MESSAGE 的构建参数,并设置了默认值。同时修改了 CMD 指令以使用这个参数。

Ctrl + X,然后按 YEnter 保存 Dockerfile

现在,我们修改 docker-compose.yml 文件来向这个构建参数传递值。打开文件进行编辑:

nano ~/project/docker-compose.yml

将内容修改为以下内容:

version: "3.8"
services:
  cow:
    build:
      context: .
      args:
        MESSAGE: "Custom message from Compose!"

我们将 build: 指令修改为一个包含 context:args: 的对象。

  • context: . 指定构建上下文,即包含 Dockerfile 的目录
  • args: 是要传递给 Dockerfile 的构建参数映射。我们向 MESSAGE 参数传递了值 "Custom message from Compose!"

Ctrl + X,然后按 YEnter 保存 docker-compose.yml 文件。

现在,我们使用构建参数来构建镜像。确保你位于 ~/project 目录下:

cd ~/project
docker-compose build

观察构建输出。你应该能看到构建参数在构建过程中被使用。

构建完成后,我们从这个镜像运行一个容器来查看输出:

docker run project_cow

你应该会看到 cowsay 输出消息 "Custom message from Compose!"。这确认了构建参数已成功传递并使用。

有时,你可能希望强制 Docker 忽略缓存并重新构建所有层。这在怀疑存在缓存问题或需要确保全新构建时很有用。你可以使用 docker-compose build 命令的 --no-cache 标志来实现。

让我们尝试使用 --no-cache 标志重新构建镜像:

docker-compose build --no-cache

再次观察构建输出。这次你会看到 Docker 没有使用任何缓存层,而是重新构建了 Dockerfile 中的每个步骤。这个过程会比使用缓存的构建花费更长时间。

构建完成后,你可以再次运行容器来确认消息仍然是构建参数传递的那个:

docker run project_cow

你应该仍然会看到 "Custom message from Compose!"。--no-cache 标志只影响构建过程,不会影响 docker-compose.yml 中定义的配置。

总结

在本实验中,你学习了如何通过安装 Docker Compose 并创建 docker-compose.yml 文件来准备一个简单的 Docker Compose 配置,使用 nginx 镜像定义服务。随后你练习了使用 docker compose build 命令构建服务,包括修改 Dockerfile 后重新构建服务,以及使用构建参数和无缓存方式构建服务。