简介
在本实验中,你将学习如何使用 docker compose push
命令将 docker-compose.yaml
文件中定义的服务镜像推送至 registry。首先,你需要准备一个包含服务镜像的 docker-compose.yaml
文件,然后构建这些镜像。最后,你将练习将这些服务镜像推送到 registry,包括如何处理推送过程中可能出现的失败情况。
在本实验中,你将学习如何使用 docker compose push
命令将 docker-compose.yaml
文件中定义的服务镜像推送至 registry。首先,你需要准备一个包含服务镜像的 docker-compose.yaml
文件,然后构建这些镜像。最后,你将练习将这些服务镜像推送到 registry,包括如何处理推送过程中可能出现的失败情况。
在本步骤中,你将学习如何创建 docker-compose.yaml
文件来定义和管理多容器 Docker 应用。Docker Compose 是一个允许你定义和运行多容器 Docker 应用的工具。通过 Compose,你可以使用 YAML 文件来配置应用服务,然后只需一条命令即可根据配置创建并启动所有服务。
首先,进入项目目录:
cd ~/project
现在,我们使用 nano
编辑器创建一个 docker-compose.yaml
文件。该文件将定义两个服务:web 服务和数据库服务。
nano docker-compose.yaml
将以下内容粘贴到 docker-compose.yaml
文件中:
version: "3.8"
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:latest
environment:
POSTGRES_PASSWORD: mysecretpassword
让我们分解这个文件:
version: '3.8'
指定 Docker Compose 文件格式版本services:
定义组成应用的不同服务web:
定义一个名为 web
的服务image: nginx:latest
指定 web
服务将使用 nginx:latest
Docker 镜像。如果本地没有该镜像,Docker 会从 Docker Hub 拉取ports:
将主机的 80 端口映射到容器的 80 端口db:
定义一个名为 db
的服务image: postgres:latest
指定 db
服务将使用 postgres:latest
Docker 镜像environment:
设置容器内的环境变量。这里我们为 PostgreSQL 数据库设置了 POSTGRES_PASSWORD
按 Ctrl + X
,然后按 Y
和 Enter
保存文件。
你可以使用 cat
命令查看已创建文件的内容:
cat docker-compose.yaml
该命令将显示你刚创建的 docker-compose.yaml
文件内容,方便你验证其内容。
在上一步中,你使用 docker-compose.yaml
文件中现有的 Docker 镜像定义了服务。本步骤将教你如何使用 Dockerfile 为服务构建自定义 Docker 镜像,并将其集成到 docker-compose.yaml
文件中。
首先,为 web 服务创建一个简单目录并在其中创建 Dockerfile。如果尚未进入项目目录,请先导航至该目录:
cd ~/project
创建名为 web
的目录并进入:
mkdir web
cd web
现在,使用 nano
编辑器在 web
目录中创建名为 Dockerfile
的文件:
nano Dockerfile
将以下内容粘贴到 Dockerfile
中:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y nginx
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
该 Dockerfile 执行以下操作:
FROM ubuntu:latest
:基于最新的 Ubuntu 基础镜像RUN apt-get update && apt-get install -y nginx
:更新软件包列表并安装 NginxCOPY index.html /var/www/html/
:将 index.html
文件(稍后创建)复制到 Nginx 网站根目录EXPOSE 80
:暴露容器的 80 端口CMD ["nginx", "-g", "daemon off;"]
:指定容器启动时运行的命令,即在前台启动 Nginx按 Ctrl + X
,然后按 Y
和 Enter
保存 Dockerfile。
现在创建 Dockerfile 中要复制的 index.html
文件。保持在 ~/project/web
目录下创建该文件:
nano index.html
将以下简单 HTML 内容粘贴到 index.html
中:
<!doctype html>
<html>
<head>
<title>Hello from Docker!</title>
</head>
<body>
<h1>Welcome to my Dockerized Nginx!</h1>
<p>This page is served from a custom Docker image.</p>
</body>
</html>
按 Ctrl + X
,然后按 Y
和 Enter
保存 index.html
文件。
现在返回包含 docker-compose.yaml
文件的项目根目录:
cd ~/project
我们需要修改 docker-compose.yaml
文件,使其使用刚创建的 Dockerfile 构建 web
服务,而非使用预构建镜像。打开 docker-compose.yaml
文件进行编辑:
nano docker-compose.yaml
将 web
服务定义从使用 image
改为使用 build
指令:
version: "3.8"
services:
web:
build: ./web
ports:
- "80:80"
db:
image: postgres:latest
environment:
POSTGRES_PASSWORD: mysecretpassword
此处 build: ./web
指示 Docker Compose 使用相对于 docker-compose.yaml
文件的 ./web
目录中的 Dockerfile 构建 web
服务的镜像。
按 Ctrl + X
,然后按 Y
和 Enter
保存修改后的 docker-compose.yaml
文件。
现在,你可以使用 docker-compose build
命令构建 docker-compose.yaml
文件中定义的镜像。由于 Docker Compose 未预装,需要先安装:
sudo apt-get update
sudo apt-get install docker-compose-plugin -y
安装 Docker Compose 插件后,可以使用 docker compose
命令(注意新版中使用空格而非连字符):
docker compose build
该命令会读取 docker-compose.yaml
文件,基于 ./web
目录中的 Dockerfile
构建 web
服务的镜像。如果本地不存在 postgres:latest
镜像,也会为 db
服务拉取该镜像。你将看到 web
镜像的构建过程输出。
构建完成后,可以列出系统中的 Docker 镜像查看新构建的镜像:
docker images
你应该能看到与项目目录和服务名称相关的镜像(如 project-web
)以及 postgres
镜像。
在上一步中,你为 web 服务构建了自定义 Docker 镜像。现在,你将学习如何将这些镜像推送至 Docker 注册表。Docker 注册表是用于存储和分发 Docker 镜像的系统。Docker Hub 是公共注册表,你也可以运行私有注册表。将镜像推送至注册表后,你可以与他人共享或在不同的机器上部署它们。
推送前,通常需要为镜像打上包含注册表地址、用户名和镜像名称的标签。为简化操作,本实验将模拟推送至本地注册表或无需身份验证的注册表。实际场景中,你需要先使用 docker login
登录注册表。
首先,列出现有镜像以识别为 web 服务构建的镜像。如果尚未进入项目目录,请先导航至该目录:
cd ~/project
列出 Docker 镜像:
docker images
你应该会看到名为 project-web
的镜像。具体名称可能因项目目录名略有不同。
现在,为 project-web
镜像打标签以便推送到注册表。我们将使用假设的注册表地址 your-registry.example.com
。实际操作时请替换为真实注册表地址。本练习将使用 localhost:5000
模拟本地注册表。
docker tag project-web localhost:5000/my-web-app:latest
该命令为 project-web
镜像打上 localhost:5000/my-web-app:latest
标签。其中 localhost:5000
是注册表地址,my-web-app
是仓库名称,latest
是标签。
你可以再次列出镜像验证新标签:
docker images
现在应该能看到 project-web
镜像显示两个标签:原始标签和 localhost:5000/my-web-app:latest
。
现在,将打好标签的镜像推送到模拟的本地注册表:
docker push localhost:5000/my-web-app:latest
由于我们模拟的本地注册表并未实际运行,该命令很可能会因连接错误而失败。这是预期结果,因为本步骤重点在于 docker push
命令本身。下一步我们将探讨如何处理此类失败情况。
在实际运行注册表的场景中,该命令会将镜像层上传至注册表。
在上一步中,你尝试将自定义 web 服务镜像推送到模拟注册表,由于注册表未运行,操作很可能失败了。某些场景下,你可能需要尝试推送多个镜像,即使其中部分推送失败也能继续执行。这在自动化脚本或向多个注册表推送时特别有用。
Docker Compose 提供了推送 docker-compose.yaml
文件中定义的所有服务镜像的方法。默认情况下,若某个镜像推送失败,整个命令将终止。但你可以使用 docker compose push
命令的 --ignore-pull-failures
标志。虽然该标志名称表示忽略拉取失败,但在 docker compose push
上下文中,根据 Compose 版本和具体情境,它也会影响推送失败的处理方式。更直接的脚本处理方式是遍历服务并尝试逐个推送,分别处理每个推送的错误。
首先列出 docker-compose.yaml
文件中定义的服务。如果尚未进入项目目录,请先导航至该目录:
cd ~/project
你可以在 docker-compose.yaml
文件中查看服务名称(web
和 db
):
cat docker-compose.yaml
现在尝试推送 docker-compose.yaml
文件中定义的所有服务。请注意 db
服务使用来自 Docker Hub 的 postgres:latest
镜像,而 web
服务是本地构建并标记为 localhost:5000
的镜像:
docker compose push
该命令将尝试推送 web
镜像(至 localhost:5000
)和 postgres
镜像(至 Docker Hub)。推送至 localhost:5000
的操作很可能如前所述失败。若你具备网络连接且目标注册表不存在该镜像,推送 postgres
至 Docker Hub 的操作可能成功(尽管通常你不会将官方镜像如 postgres
推送到自己的注册表)。由于无法连接 localhost:5000
,该命令很可能会报告失败。
为演示忽略失败的情况,假设你拥有多个服务并希望独立推送它们,即使某个推送失败也能继续。虽然 docker compose push
没有像处理拉取失败那样直接提供"忽略所有服务推送失败"的标志,但你可以通过编写脚本遍历服务并尝试逐个推送来实现类似效果。
例如,你可以编写一个尝试逐个推送服务并在出错时继续的脚本。但为了本实验目的及演示推送操作中处理潜在失败的概念,我们将重点关注 docker compose push
命令的结果,该命令会在目标注册表不可达时突出显示失败。
关键要点在于理解镜像推送是 CI/CD 流水线中的关键步骤,处理潜在失败(如网络问题或认证问题)非常重要。虽然 docker compose push
默认可能在首个错误时停止,但在脚本或更高级场景中,你需要实现处理单个推送结果的逻辑。
让我们确认 docker compose push
命令已执行:
grep "docker compose push" ~/.zsh_history
这将确认你已尝试使用 Docker Compose 推送镜像。命令本身的输出会显示 web
服务推送的失败情况。
在本实验中,你学习了如何准备 docker-compose.yaml
文件来定义多容器 Docker 应用,具体配置了 web 服务器(nginx)和数据库(PostgreSQL)等服务,包括它们各自的镜像、端口和环境变量。随后你练习了基于 docker-compose.yaml
文件中的定义构建这些服务镜像。
此外,你还探索了如何使用 docker compose push
命令将这些构建好的服务镜像推送到 Docker 注册表。通过使用 --ignore-push-failures
标志,你学会了如何处理推送过程中可能出现的失败情况,使得即使部分镜像上传失败,推送操作也能继续进行。