自定义 Docker 镜像

DockerDockerBeginner
立即练习

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

简介

Docker 是一个强大的工具,用于将应用程序打包并作为容器分发。此过程的核心是 Docker 镜像,它们是预先构建的包,包含运行应用程序所需的一切,包括代码、依赖项和配置。在本实验中,你将学习如何创建自定义 Docker 镜像,通过整合额外的软件、库或配置来增强你的应用程序。

在整个实验中,我们将使用 WebIDE (VS Code) 来编辑文件。WebIDE 提供了一个熟悉且用户友好的界面,用于文件编辑,使处理配置文件和代码更容易。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 95%。获得了学习者 99% 的好评率。

设置项目环境

让我们首先创建一个项目目录并导航到它。

在整个实验中,我们将使用 WebIDE (VS Code) 来编辑文件。WebIDE 提供了一个熟悉且用户友好的界面,用于文件编辑,使处理配置文件和代码更容易。

  1. 在 WebIDE 中打开一个终端。你可以通过点击顶部菜单中的“Terminal”,然后选择“New Terminal”来完成此操作。
  2. 在终端中,运行以下命令:
mkdir -p ~/project/docker
cd ~/project/docker

这将在 ~/project 文件夹中创建一个名为 docker 的新目录,并将当前工作目录更改为该目录。

  1. 验证你是否在正确的目录中:
pwd

你应该看到 /home/labex/project/docker 作为输出。

理解这些命令:

  • mkdir -p: 此命令创建一个目录。-p 标志允许它在父目录不存在时创建它们。
  • cd: 此命令更改当前目录。
  • pwd: 此命令打印当前工作目录。

创建一个简单的 Docker 镜像

现在,让我们创建一个运行 Nginx Web 服务器的简单 Docker 镜像。

  1. 在 WebIDE 中,导航到文件资源管理器(通常是左侧边栏中的第一个图标)。
  2. 在文件资源管理器窗格中右键单击,然后选择“New File”。将其命名为 Dockerfile(以大写字母“D”开头,且没有文件扩展名)。
  3. 通过在文件资源管理器中单击它来打开 Dockerfile。添加以下内容:
FROM nginx
COPY index.html /usr/share/nginx/html/

此 Dockerfile 定义了一个基于官方 Nginx 镜像的新镜像,并将名为 index.html 的文件复制到 Nginx 的默认文档根目录。

理解 Dockerfile:

  • FROM nginx: 此行指定我们正在构建的 base 镜像。在本例中,我们使用官方 Nginx 镜像。
  • COPY index.html /usr/share/nginx/html/: 此行将我们的 index.html 文件复制到容器的 Web 根目录。
  1. 在同一目录中创建一个名为 index.html 的新文件。你可以再次在文件资源管理器窗格中右键单击并选择“New File”来完成此操作。
  2. 打开 index.html 并添加以下内容:
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hello Docker!</title>
  </head>
  <body>
    <h1>Hello Docker!</h1>
    <p>This is a custom Docker image.</p>
  </body>
</html>

这是一个简单的 HTML 页面,将由我们的 Nginx 服务器提供服务。

  1. 在 WebIDE 中打开一个终端(如果关闭了之前的终端,则为 Terminal -> New Terminal),并使用以下命令构建 Docker 镜像:
docker build -t my-nginx .

此命令使用标签 my-nginx 构建一个新的 Docker 镜像。

理解该命令:

  • docker build: 这是构建 Docker 镜像的命令。
  • -t my-nginx: -t 标志使用名称 my-nginx 标记我们的镜像。
  • .: 这将构建上下文(包含 Dockerfile 的目录)指定为当前目录。
  1. 构建完成后,验证镜像是否已成功创建:
docker images

你应该在输出中看到 my-nginx 镜像。

运行并测试自定义镜像

让我们运行一个基于我们新镜像的容器并对其进行测试。

  1. 在 WebIDE 终端中,使用以下命令启动一个容器:
docker run -d -p 8080:80 --name my-nginx-container my-nginx

理解此命令:

  • docker run: 此命令创建并启动一个新容器。
  • -d: 此标志以分离模式(在后台)运行容器。
  • -p 8080:80: 这将你的主机上的端口 8080 映射到容器中的端口 80。
  • --name my-nginx-container: 这为我们的容器分配一个名称。
  • my-nginx: 这是我们用来创建容器的镜像的名称。
  1. 验证容器是否正在运行:
docker ps

你应该在输出中看到 my-nginx-container。此命令显示所有正在运行的容器。

  1. 要查看网页的内容,请使用 curl 命令:
curl http://localhost:8080

你应该在终端中看到 index.html 文件的 HTML 内容。

如果你对 curl 的作用感到好奇,它是一个用于从服务器传输数据或向服务器传输数据的工具。在本例中,我们使用它来从我们的 Web 服务器获取内容。

你也可以导航到 LabEx VM 的顶部,然后单击 + 创建一个新的 Web 服务器,然后输入端口 8080 来查看内容。

Web server port setup

向镜像添加自定义软件

现在,让我们修改我们的 Docker 镜像以包含额外的软件。我们将添加 curl 实用程序作为示例。

  1. 在 WebIDE 中,打开 Dockerfile。你可以通过在文件资源管理器窗格中单击 Dockerfile 来完成此操作。
  2. 修改 Dockerfile 的内容为:
FROM nginx
RUN apt-get update && apt-get install -y curl
COPY index.html /usr/share/nginx/html/

此 Dockerfile 添加了一个新的 RUN 指令,该指令更新包索引并使用 apt-get 包管理器安装 curl 实用程序。

理解新行:

  • RUN apt-get update && apt-get install -y curl: 此行更新包列表 (apt-get update),然后安装 curl (apt-get install -y curl)。-y 标志在安装期间自动回答“yes”以响应任何提示。
  1. 在 WebIDE 中按 Ctrl+S(或在 Mac 上按 Cmd+S)保存文件。
  2. 在 WebIDE 终端中,使用新标签重建 Docker 镜像:
docker build -t my-nginx-curl .

此命令使用标签 my-nginx-curl 构建一个新的 Docker 镜像,其中包含 curl 实用程序。

  1. 验证新镜像是否已创建:
docker images

你应该在输出中看到 my-nginx-curl 镜像。

使用 Curl 测试自定义镜像

让我们运行一个基于我们新镜像的容器并测试 curl 实用程序。

  1. 在 WebIDE 终端中,使用以下命令启动一个新容器:
docker run -d --name curl-container my-nginx-curl

此命令基于 my-nginx-curl 镜像启动一个新容器,并将其命名为 curl-container

  1. 在正在运行的容器中执行 bash shell:
docker exec -it curl-container bash

此命令在正在运行的容器内打开一个交互式 bash shell。

理解此命令:

  • docker exec: 这在正在运行的容器中运行一个命令。
  • -it: 这些标志分配一个伪 TTY 并保持 STDIN 打开,允许你与 shell 交互。
  • curl-container: 这是我们容器的名称。
  • bash: 这是我们在容器中运行的命令(打开一个 bash shell)。
  1. 你现在应该看到一个新的提示符,表明你位于容器内部。在容器内部,测试 curl 实用程序:
curl http://localhost

你应该在终端中看到 index.html 文件的 HTML 内容。

  1. 退出容器的 bash shell:
exit

此命令将你返回到你的主机系统的 shell。

在镜像中使用环境变量

在这一步中,我们将修改我们的 Docker 镜像以使用环境变量进行自定义。

  1. 在 WebIDE 中,再次打开 Dockerfile

  2. 修改 Dockerfile 的内容为:

FROM nginx
ENV NGINX_PORT 9000
RUN sed -i "s/listen\s*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf
COPY index.html /usr/share/nginx/html/

此 Dockerfile 添加了一个 ENV 指令,该指令将 NGINX_PORT 变量设置为 9000。它还包括一个 RUN 指令,该指令修改 Nginx 配置以使用此端口。

理解新行:

  • ENV NGINX_PORT 9000: 这设置了一个环境变量 NGINX_PORT,其值为 9000
  • RUN sed -i "s/listen\s*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf: 这使用 sed 在 Nginx 配置文件中将默认端口 (80) 替换为我们的环境变量。
  1. 在 WebIDE 中保存文件。

  2. 在 WebIDE 终端中,使用新标签重建 Docker 镜像:

docker build -t my-nginx-env .
  1. 运行一个基于新镜像的容器:
docker run -d -p 9000:9000 --name env-container my-nginx-env

此命令基于 my-nginx-env 镜像启动一个新容器,并将主机上的端口 9000 映射到容器中的端口 9000。请注意,环境变量已经在 Dockerfile 中设置,因此无需在 docker run 命令中再次设置它。

  1. 验证 Web 服务器是否正在指定的端口上运行:
curl http://localhost:9000

你应该在终端中看到 index.html 文件的 HTML 内容。

在 Dockerfile 中使用 ENTRYPOINT

在这一步中,我们将学习如何在 Dockerfile 中使用 ENTRYPOINT 指令并使用不同的端口 (9100)。

  1. 在 WebIDE 中,再次打开 Dockerfile

  2. 修改 Dockerfile 的内容为:

FROM nginx
ENV NGINX_PORT 9100
RUN sed -i "s/listen\s*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf
COPY index.html /usr/share/nginx/html/
COPY start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]

此 Dockerfile 将 NGINX_PORT 设置为 9100,并添加一个 ENTRYPOINT 指令,该指令指定容器启动时要运行的命令。

  1. 在同一目录下创建一个名为 start.sh 的新文件,其内容如下:
#!/bin/bash
echo "Starting Nginx on port $NGINX_PORT"
nginx -g 'daemon off;'

此脚本在启动 Nginx 之前打印一条消息,显示 Nginx 将在哪个端口上运行。

  1. 在 WebIDE 中保存这两个文件。

  2. 在 WebIDE 终端中,使用新标签重建 Docker 镜像:

docker build -t my-nginx-entrypoint .
  1. 运行一个基于新镜像的容器:
docker run -d -p 9100:9100 -e NGINX_PORT=9100 --name entrypoint-container my-nginx-entrypoint
  1. 检查容器日志以查看启动消息:
docker logs entrypoint-container

你应该在输出中看到消息 "Starting Nginx on port 9100"。

  1. 验证 Web 服务器是否在新端口上正确运行:
curl http://localhost:9100

你应该在终端中看到 index.html 文件的 HTML 内容。

总结

在这个实验中,你已经学会了如何创建自定义 Docker 镜像,从而为你的应用程序增加价值。你首先创建了一个带有 Web 服务器的简单镜像,然后逐步添加了自定义软件,并使用环境变量进行配置。在整个实验过程中,你使用了 WebIDE (VS Code) 来编辑文件,这使得该过程更加直观和用户友好。

以下是你已经完成的工作的总结:

  1. 设置了一个项目环境,并学习了基本的终端命令。
  2. 创建了一个简单的 Docker 镜像,其中包含 Nginx 和一个自定义 HTML 页面。
  3. 构建并运行了 Docker 容器,学习了端口映射和容器命名。
  4. 修改了 Docker 镜像以包含额外的软件 (curl)。
  5. 使用 Docker exec 在容器内运行命令。
  6. 将环境变量合并到你的 Docker 镜像中,以便于配置。