简介
Docker 是一个用于将应用程序打包并分发为容器的强大工具。这一过程的核心是 Docker 镜像,它是预先构建好的包,包含了运行应用程序所需的一切,包括代码、依赖项和配置。在本实验中,你将学习如何通过整合额外的软件、库或配置来创建自定义 Docker 镜像,从而增强你的应用程序。
在整个实验过程中,我们将使用 WebIDE (VS Code) 来编辑文件。WebIDE 提供了一个熟悉且用户友好的文件编辑界面,使得处理配置文件和代码变得更加简单。
设置项目环境
让我们从创建一个项目目录并进入该目录开始。
在整个实验过程中,我们将使用 WebIDE (VS Code) 来编辑文件。WebIDE 提供了一个熟悉且用户友好的文件编辑界面,使得处理配置文件和代码变得更加简单。
- 在 WebIDE 中打开终端。你可以通过点击顶部菜单栏的「Terminal」,然后选择「New Terminal」来完成。
- 在终端中运行以下命令:
mkdir -p ~/project/docker
cd ~/project/docker

这会在 ~/project 文件夹下创建一个名为 docker 的新目录,并将当前工作目录切换到该目录。
- 验证你是否处于正确的目录中:
pwd
你应该会看到输出 /home/labex/project/docker。
命令解析:
mkdir -p:此命令用于创建目录。-p标志允许在父目录不存在时一并创建它们。cd:此命令用于切换当前目录。pwd:此命令用于打印当前工作目录。
创建一个简单的 Docker 镜像
现在,让我们创建一个运行 Nginx Web 服务器的简单 Docker 镜像。
- 在 WebIDE 中,导航到文件资源管理器(通常是左侧边栏的第一个图标)。
- 在文件资源管理器面板中右键点击,选择「New File」。将其命名为
Dockerfile(注意首字母大写,且没有文件扩展名)。 - 点击文件资源管理器中的
Dockerfile将其打开,并添加以下内容:
FROM nginx
COPY index.html /usr/share/nginx/html/
此 Dockerfile 定义了一个基于官方 Nginx 镜像的新镜像,并将一个名为 index.html 的文件复制到 Nginx 的默认文档根目录中。
Dockerfile 解析:
FROM nginx:此行指定了我们构建所基于的基础镜像。在本例中,我们使用的是官方 Nginx 镜像。COPY index.html /usr/share/nginx/html/:此行将我们的index.html文件复制到容器的 Web 根目录中。
- 在同一目录下创建一个名为
index.html的新文件。你可以再次在文件资源管理器面板中右键点击并选择「New File」来完成。 - 打开
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 服务器提供服务。
- 在 WebIDE 中打开终端(如果关闭了之前的终端,请点击 Terminal -> New Terminal),并使用以下命令构建 Docker 镜像:
docker build -t my-nginx .
此命令构建了一个标签为 my-nginx 的新 Docker 镜像。
命令解析:
docker build:这是构建 Docker 镜像的命令。-t my-nginx:-t标志为我们的镜像打上my-nginx的标签。.:这指定了构建上下文(包含 Dockerfile 的目录)为当前目录。
- 构建完成后,验证镜像是否创建成功:
docker images
你应该能在输出中看到 my-nginx 镜像。
运行并测试自定义镜像
让我们运行一个基于我们新镜像的容器并进行测试。
- 在 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:这是我们用于创建容器的镜像名称。
- 验证容器是否正在运行:
docker ps
你应该能在输出中看到 my-nginx-container。此命令会显示所有正在运行的容器。
- 要查看网页内容,请使用
curl命令:
curl http://localhost:8080
你应该能在终端中看到 index.html 文件的 HTML 内容。
如果你对 curl 的作用感到好奇,它是一个用于在服务器之间传输数据的工具。在本例中,我们使用它从我们的 Web 服务器获取内容。
你也可以导航到 LabEx 虚拟机顶部,点击「+」号创建一个新的 Web 服务器,然后输入端口 8080 来查看内容。

向镜像添加自定义软件
在这一步中,你将修改 Docker 镜像以包含额外的软件。我们将添加 nano 文本编辑器作为示例,因为它未包含在基础 nginx 镜像中。
- 在 WebIDE 中打开
Dockerfile。你可以通过点击文件资源管理器面板中的Dockerfile来完成。 - 将
Dockerfile的内容修改为:
FROM nginx
RUN apt-get update && apt-get install -y nano
COPY index.html /usr/share/nginx/html/
此 Dockerfile 添加了一条新的 RUN 指令,它使用 apt-get 包管理器更新包索引并安装 nano 包。
新行解析:
RUN apt-get update && apt-get install -y nano:此行更新包列表(apt-get update),然后安装nano(apt-get install -y nano)。-y标志会自动对安装过程中的任何提示回答「yes」。
- 在 WebIDE 中按 Ctrl+S(Mac 上为 Cmd+S)保存文件。
- 在 WebIDE 终端中,使用新标签重新构建 Docker 镜像:
docker build -t my-nginx-nano .
此命令构建了一个标签为 my-nginx-nano 的新 Docker 镜像,其中包含了 nano 编辑器。
- 验证新镜像是否已创建:
docker images
你应该能在输出中看到 my-nginx-nano 镜像。
使用 Nano 测试自定义镜像
在这一步中,你将运行一个基于新镜像的容器,并确认 nano 包在其中可用。
- 在 WebIDE 终端中,使用以下命令启动一个新容器:
docker run -d --name nano-container my-nginx-nano
此命令启动了一个基于 my-nginx-nano 镜像的新容器,并将其命名为 nano-container。
- 运行以下命令检查容器内安装的
nano版本:
docker exec nano-container nano --version
此命令在正在运行的容器内执行 nano --version,以便你确认该包已安装。
命令解析:
docker exec:此命令在正在运行的容器中执行命令。nano-container:这是我们容器的名称。nano --version:这会打印容器内安装的nano版本。
- 你应该能看到以
GNU nano开头的输出,这证实了自定义镜像现在包含了该编辑器。
在镜像中使用环境变量
在这一步中,我们将修改 Docker 镜像以使用环境变量进行自定义。
在 WebIDE 中再次打开
Dockerfile。将
Dockerfile的内容修改为:
FROM nginx
ENV NGINX_PORT 9000
RUN sed -i "s/listen[[:space:]]*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:这设置了一个值为9000的环境变量NGINX_PORT。RUN sed -i "s/listen[[:space:]]*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf:这使用sed将 Nginx 配置文件中的默认端口 (80) 替换为我们的环境变量。
在 WebIDE 中保存文件。
在 WebIDE 终端中,使用新标签重新构建 Docker 镜像:
docker build -t my-nginx-env .
- 运行一个基于新镜像的容器:
docker run -d -p 9000:9000 --name env-container my-nginx-env
此命令启动了一个基于 my-nginx-env 镜像的新容器,并将宿主机的 9000 端口映射到容器内的 9000 端口。请注意,环境变量已在 Dockerfile 中设置,因此无需在 docker run 命令中再次设置。
- 验证 Web 服务器是否在指定的端口上运行:
curl http://localhost:9000
你应该能在终端中看到 index.html 文件的 HTML 内容。
在 Dockerfile 中使用 ENTRYPOINT
在这一步中,我们将学习如何在 Dockerfile 中使用 ENTRYPOINT 指令,并使用不同的端口 (9100)。
在 WebIDE 中再次打开
Dockerfile。将
Dockerfile的内容修改为:
FROM nginx
COPY index.html /usr/share/nginx/html/
COPY start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]
此 Dockerfile 移除了环境变量和 sed 命令。相反,我们将使用 ENTRYPOINT 脚本在运行时处理配置。这使得我们的镜像更加灵活。
- 在同一目录下创建一个名为
start.sh的新文件,内容如下:
#!/bin/bash
## Set a default port if NGINX_PORT is not set
export NGINX_PORT=${NGINX_PORT:-9100}
## Replace the port in the nginx configuration
sed -i "s/listen[[:space:]]*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf
echo "Starting Nginx on port $NGINX_PORT"
nginx -g 'daemon off;'
此脚本设置了一个默认端口,在容器启动时修改 Nginx 配置,打印出 Nginx 将运行的端口信息,然后启动 Nginx。
在 WebIDE 中保存这两个文件。
在 WebIDE 终端中,使用新标签重新构建 Docker 镜像:
docker build -t my-nginx-entrypoint .
- 运行一个基于新镜像的容器。我们将使用环境变量将端口设置为 9100。
docker run -d -p 9100:9100 -e NGINX_PORT=9100 --name entrypoint-container my-nginx-entrypoint
- 查看容器日志以查看启动消息:
docker logs entrypoint-container
你应该能在输出中看到消息「Starting Nginx on port 9100」。
- 验证 Web 服务器是否在新端口上正确运行:
curl http://localhost:9100
你应该能在终端中看到 index.html 文件的 HTML 内容。
总结
在本实验中,你学习了如何创建能够为应用程序增值的自定义 Docker 镜像。你从创建一个带有 Web 服务器的简单镜像开始,然后逐步学习了如何添加自定义软件以及如何使用环境变量进行配置。在整个实验过程中,你使用了 WebIDE (VS Code) 来编辑文件,这使得整个过程更加直观和友好。
以下是你所完成工作的回顾:
- 设置了项目环境并学习了基本的终端命令。
- 创建了一个带有 Nginx 和自定义 HTML 页面的简单 Docker 镜像。
- 构建并运行了 Docker 容器,学习了端口映射和容器命名。
- 修改了 Docker 镜像以包含额外的软件 (curl)。
- 使用
docker exec在容器内运行命令。 - 将环境变量整合到 Docker 镜像中,以便于配置。



