介绍
本教程是一份全面的 Docker 指南,旨在为开发者和 IT 专业人士提供对容器技术的深入了解。从理解核心 Docker 概念到实际的安装和管理技术,本指南涵盖了利用 Docker 强大的容器化能力进行现代软件开发和部署所需的一切。
本教程是一份全面的 Docker 指南,旨在为开发者和 IT 专业人士提供对容器技术的深入了解。从理解核心 Docker 概念到实际的安装和管理技术,本指南涵盖了利用 Docker 强大的容器化能力进行现代软件开发和部署所需的一切。
Docker 是一个强大的容器技术平台,它使开发者能够高效地打包、分发和运行应用程序。容器提供轻量级、可移植的环境,封装了软件及其依赖项。
概念 | 描述 |
---|---|
Docker Image | 包含应用程序代码和依赖项的只读模板 |
Container | Docker 镜像的可运行实例 |
Docker Engine | 用于创建和管理容器的运行时环境 |
你的 LabEx 环境已预装 Docker。让我们验证 Docker 版本,以确保它已准备就绪。
docker --version
输出应显示 Docker 版本,例如 Docker version 20.10.21, build baeda1f
。这证实 Docker 已正确安装并可访问。
Docker 镜像是一个只读模板,其中包含创建容器的一系列指令。我们将拉取 hello-world
镜像,这是一个用于测试 Docker 安装的最小镜像。
docker pull hello-world
此命令将 Docker Hub 中的 hello-world
镜像下载到你的本地机器。你应该会看到指示下载进度和镜像已拉取的确认信息。
现在我们有了镜像,让我们从中运行一个容器。运行容器意味着创建一个镜像的实例。
docker run hello-world
当你运行 hello-world
时,Docker 会执行以下操作:
hello-world
镜像是否已存在于本地。如果不存在,它会将其拉取(我们已经完成了这一步)。这演示了 Docker 容器的基本生命周期:拉取镜像,运行容器,然后容器执行其定义的任务。
要查看你已下载的镜像,请使用 docker images
命令。
docker images
此命令会列出存储在你本地系统上的所有 Docker 镜像,包括我们刚刚拉取的 hello-world
镜像。你将看到诸如仓库、标签、镜像 ID、创建日期和大小等详细信息。
容器提供隔离的环境,拥有自己的文件系统、进程和网络接口。它们可以被快速地启动、停止、移动和删除,这使得它们成为微服务和云原生应用程序的理想选择。
Dockerfile 是一个文本文档,其中包含用户在命令行中可以调用的所有指令,用于构建镜像。它定义了容器化应用程序的环境、依赖项和配置。
导航到 docker_app
目录,该目录在设置阶段已创建。这将是我们本次实验的工作目录。
cd /home/labex/project/docker_app
现在,让我们在此目录中创建一个名为 Dockerfile
的简单 Dockerfile。此 Dockerfile 将创建一个基于 Ubuntu 的镜像,并向其中添加一个简单的文本文件。
nano Dockerfile
向 Dockerfile
添加以下内容:
## 使用官方 Ubuntu 基础镜像
FROM ubuntu:22.04
## 设置容器内的工作目录
WORKDIR /app
## 创建一个简单的文本文件
RUN echo "Hello from Dockerfile!" > /app/message.txt
## 容器启动时执行的命令
CMD ["cat", "/app/message.txt"]
FROM ubuntu:22.04
: 此指令指定了我们新镜像的基础镜像。我们使用的是 Ubuntu 22.04。WORKDIR /app
: 此指令设置了 Dockerfile 中后续所有 RUN
、CMD
、ENTRYPOINT
、COPY
或 ADD
指令的工作目录。如果 /app
不存在,它将被创建。RUN echo "Hello from Dockerfile!" > /app/message.txt
: 此指令在构建过程中在镜像内执行一个命令。在这里,它在 /app
目录中创建了一个名为 message.txt
的文件,内容为 "Hello from Dockerfile!"。CMD ["cat", "/app/message.txt"]
: 此指令为正在运行的容器提供了默认命令。当从该镜像运行容器时,它将执行 cat /app/message.txt
,显示我们消息文件的内容。按 Ctrl+S
保存文件,然后按 Ctrl+X
退出 nano
。
现在我们有了 Dockerfile,让我们从中构建 Docker 镜像。docker build
命令会读取 Dockerfile 并创建一个 Docker 镜像。
docker build -t my-ubuntu-app .
docker build
: 构建 Docker 镜像的命令。-t my-ubuntu-app
: 这将我们的镜像标记为 my-ubuntu-app
。你可以选择任何你喜欢的名称。.
: 这指定了构建上下文,即指定路径或 URL 处的文件的集合。.
表示当前目录 (/home/labex/project/docker_app
) 是构建上下文。Docker 将在此目录中查找 Dockerfile
。你将看到显示构建过程每一步的输出,对应于 Dockerfile 中的指令。
成功构建镜像后,让我们从中运行一个容器来查看 message.txt
的内容。
docker run my-ubuntu-app
此命令将从你的 my-ubuntu-app
镜像创建一个新容器并运行它。你的 Dockerfile 中的 CMD
指令将被执行,你应该会在终端看到 "Hello from Dockerfile!" 被打印出来。
为了进一步了解容器内文件的管理方式,让我们运行一个交互式会话并检查我们创建的文件。
docker run -it my-ubuntu-app /bin/bash
-it
: 此标志分配一个伪终端(pseudo-TTY)并保持 STDIN
打开,允许你与容器进行交互。my-ubuntu-app
: 我们想要运行的镜像名称。/bin/bash
: 这会覆盖 Dockerfile 中的 CMD
指令,转而在容器内运行 Bash shell,为你提供一个命令提示符。进入容器后,你将看到一个新的命令提示符(例如 root@<container_id>:/app#
)。现在,你可以列出文件并查看 message.txt
的内容。
ls -l
cat message.txt
你应该会看到 message.txt
被列出,并且其内容被显示出来。要退出容器,只需键入 exit
。
exit
这个交互式会话表明文件 message.txt
已成功创建,并且可以在容器的文件系统中访问。
多阶段构建是一项强大功能,它允许你在 Dockerfile 中使用多个 FROM
语句。每个 FROM
指令都可以使用不同的基础镜像,并且每个 FROM
指令都会启动一个新的构建阶段。通过分离构建和运行时环境,这有助于优化 Dockerfile 的复杂性并减小最终镜像的大小。
在本示例中,我们将模拟一个需要构建步骤的简单应用程序。我们将创建一个 build_script.sh
和一个 final_app.txt
文件。
首先,请确保你位于 docker_app
目录:
cd /home/labex/project/docker_app
现在,创建一个简单的构建脚本:
nano build_script.sh
向 build_script.sh
添加以下内容:
#!/bin/bash
echo "Running build process..."
echo "This is the final application output." > /app/output/final_app.txt
echo "Build complete."
保存文件(Ctrl+S
)并退出(Ctrl+X
)。
接下来,为我们的最终应用程序内容创建一个占位符。在实际场景中,这会由构建过程生成。
nano final_app.txt
向 final_app.txt
添加以下内容:
This is a placeholder for the final application.
保存文件(Ctrl+S
)并退出(Ctrl+X
)。
现在,让我们修改我们的 Dockerfile
以使用多阶段构建。我们将有一个“构建器”阶段来运行我们的 build_script.sh
,然后是一个“生产”阶段,它只从构建器阶段复制必要的输出。
nano Dockerfile
将现有内容替换为以下内容:
## Stage 1: Builder stage
FROM ubuntu:22.04 AS builder
## 安装 bash 以运行脚本
RUN apt-get update && apt-get install -y bash
## 设置构建器阶段的工作目录
WORKDIR /build
## 复制构建脚本并使其可执行
COPY build_script.sh .
RUN chmod +x build_script.sh
## 创建一个输出目录
RUN mkdir -p /build/output
## 运行构建脚本
RUN ./build_script.sh
## Stage 2: Production stage
FROM ubuntu:22.04
## 设置生产阶段的工作目录
WORKDIR /app
## 只从构建器阶段复制必要的产物
COPY --from=builder /build/output/final_app.txt .
## 容器启动时执行的命令
CMD ["cat", "final_app.txt"]
FROM ubuntu:22.04 AS builder
: 这启动了第一个阶段并将其命名为 builder
。RUN apt-get update && apt-get install -y bash
: 在构建器阶段安装 bash
,这是运行我们的脚本所必需的。WORKDIR /build
: 设置构建器阶段的工作目录。COPY build_script.sh .
: 将我们的构建脚本复制到构建器阶段。RUN chmod +x build_script.sh
: 使脚本可执行。RUN mkdir -p /build/output
: 在构建器阶段创建一个输出目录。RUN ./build_script.sh
: 执行构建脚本,该脚本在 /build/output
中生成 final_app.txt
。FROM ubuntu:22.04
: 这启动了第二个阶段(生产阶段)。它使用了一个新的 ubuntu:22.04
镜像,这意味着它默认不会继承 builder
阶段的任何内容。WORKDIR /app
: 设置生产阶段的工作目录。COPY --from=builder /build/output/final_app.txt .
: 这是多阶段构建的关键指令。它将 builder
阶段的 /build/output
目录中的 final_app.txt
复制到生产阶段的当前目录(/app
)。这确保了只包含最终产物,从而使生产镜像保持较小。CMD ["cat", "final_app.txt"]
: 生产容器启动时要执行的命令,显示复制文件的内容。保存文件(Ctrl+S
)并退出(Ctrl+X
)。
现在,让我们使用我们的多阶段 Dockerfile 构建新镜像。
docker build -t multi-stage-app .
观察构建输出。你将看到 builder
阶段和最终阶段的步骤。
构建完成后,运行容器以验证是否显示了 final_app.txt
的内容。
docker run multi-stage-app
你应该会看到 "This is the final application output." 被打印出来,这证实了多阶段构建已成功将产物从构建阶段复制到最终镜像。
清理不再需要的 Docker 资源(容器和镜像)以释放磁盘空间是一个好习惯。
首先,列出所有容器(包括已退出的):
docker ps -a
你可以通过容器的 ID 或名称删除特定容器:
docker rm $(docker ps -aq)
此命令会删除所有已退出的容器。docker ps -aq
列出所有容器 ID,docker rm
则删除它们。
接下来,列出所有镜像:
docker images
你可以通过镜像的 ID 或名称删除特定镜像。请注意不要删除仍被运行中的容器使用的镜像。
docker rmi my-ubuntu-app multi-stage-app hello-world ubuntu:22.04
此命令会删除我们在本次实验中创建和使用的镜像。如果镜像仍被容器使用,你需要先删除该容器。
docker images
此命令将显示镜像已被删除。
至此,关于 Docker 基础和高级技术的实验结束。你已经学会了如何创建 Dockerfile、构建镜像、运行容器以及使用多阶段构建优化镜像大小。
通过掌握 Docker 基础知识、Dockerfile 管理和高级技术,开发者可以创建更高效、可移植且可扩展的软件环境。本教程为你提供了容器创建、镜像管理和部署策略方面的实践技能,使你能够简化开发工作流程并拥抱云原生应用程序架构。