2.4 构建镜像

实验简介
在Docker的世界中,镜像是容器的基础,而自定义镜像则是应用容器化的关键。本实验将介绍两种构建自定义镜像的方法:
- 使用
docker commit命令将运行中的容器保存为新镜像 - 使用Dockerfile文件定义镜像构建过程,并通过
docker build命令构建镜像
通过这两种方法,我们可以将应用程序、配置文件和依赖项打包成一个可移植的镜像,便于分发和部署。
任务一:使用 docker commit 构建
docker commit命令允许我们将运行中容器的当前状态保存为新镜像。这种方法特别适合在容器中进行交互式操作后,将结果保存下来。
基本操作流程是:运行容器 → 修改容器 → 保存修改后的容器
在这个任务中,我们将使用Alpine Linux作为基础镜像,安装Nginx并部署一个简单的网站,然后将这个定制化的容器保存为新镜像。

1. 运行Alpine容器
首先,我们启动一个Alpine Linux容器,并进入交互式模式:
docker run -it -p 80:80 --name working alpine

/ #表示我们已经进入了容器的 Shell 环境。2. 更新软件包索引
在容器内执行以下命令,更新软件包索引:
apk update

apk是Alpine Linux的包管理器,类似于Ubuntu的apt或CentOS的yum。
3. 安装必要的软件包
临时解决实验室的网络问题(外部环境不需要此步骤):
export HTTP_PROXY=http://192.168.192.199:10809
export HTTPS_PROXY=http://192.168.192.199:10809
接下来,我们安装Web服务器和其他工具:
apk add wget nginx vim
这个命令安装了三个软件包:
wget:用于从网络下载文件nginx:高性能Web服务器vim:文本编辑器
4. 创建Nginx配置文件
删除默认配置并创建自定义配置:
rm /etc/nginx/http.d/default.conf
vim /etc/nginx/http.d/mysite.conf
在编辑器中粘贴以下配置内容:
server {
listen 80 default_server;
location / {
root /var/www/localhost/htdocs;
index index.html;
}
}
/var/www/localhost/htdocs。当访问网站时,默认显示index.html文件。5. 部署网站内容
切换到网站根目录并下载网站文件:
cd /var/www/localhost/htdocs
# 下载网站文件
wget https://git.seahi.me/seahi/docker/raw/branch/main/2.4%E6%9E%84%E5%BB%BA%E9%95%9C%E5%83%8F/index.html
wget https://git.seahi.me/seahi/docker/raw/branch/main/2.4%E6%9E%84%E5%BB%BA%E9%95%9C%E5%83%8F/styles.css

6. 启动Nginx服务
现在我们启动Nginx服务器
nginx
在浏览器中访问服务器IP地址,应该能看到我们部署的网站:

7. 将容器保存为镜像
按下Ctrl+C停止Nginx服务,然后退出容器:
exit
现在使用docker commit命令将修改后的容器保存为新镜像:
docker commit working mysite:v0.1
现在,我们已经成功地将一个运行中的容器保存为新镜像mysite:v0.1。这个镜像包含了Alpine Linux、Nginx和我们部署的网站内容。
任务二:通过Dockerfile构建
虽然docker commit方法简单直观,但它缺乏可重复性和透明度。使用Dockerfile构建镜像是更推荐的方法,它提供了清晰的构建步骤文档,便于版本控制和自动化构建。
docker commit 的典型缺点。在本任务中,你需要为一个简单的问候网站创建Docker镜像。这个网站会显示"Hello from Docker!“并展示访问次数。
1. 准备工作目录和源文件
首先,创建一个新的工作目录并下载网站文件:
mkdir /root/myflask
cd /root/myflask
在该目录下准备两个文件:
app.py
from flask import Flask
import redis
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
@app.route('/')
def hello():
count = get_hit_count()
return f'Hello from Docker! 访问次数: {count}\n'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
requirements.txt
flask==2.3.0
redis==4.5.0
2. 创建Dockerfile
在工作目录中创建一个名为Dockerfile的文件:
vim Dockerfile
按要求编写Dockerfile
要求一:
- 基础镜像:python:3.9-alpine
- 工作目录:/app
- 复制宿主机的 requirements.txt 到容器内的工作目录
- 安装依赖:
pip install --no-cache-dir -r requirements.txt - 复制宿主机的 app.py 到容器内的工作目录
- 暴露端口:5000
- 启动命令:
python app.py
要求二:元数据标签
添加以下标签信息:
maintainer- 你的姓名version- 1.0.0project- “myflask”build-date- 当前日期(格式:2024-01-15)
要求三:环境变量
设置以下环境变量:
PYTHONUNBUFFERED=1(Python输出不缓冲)FLASK_APP=app.pyFLASK_ENV=productionFLASK_HOST=0.0.0.0FLASK_PORT=5000TZ=Asia/Shanghai(设置时区)
3. 构建镜像
使用docker build命令构建镜像:
docker build -t 镜像名 .
参数说明:
-t:指定镜像的标签(名称和版本).:指定构建上下文(当前目录)
两种构建方法的对比
docker commit
- 优点:简单直观,适合快速原型开发和探索
- 缺点:构建过程不透明,难以重现,不适合团队协作和自动化
Dockerfile
- 优点:构建过程透明,易于版本控制,支持自动化,是业界最佳实践
- 缺点:需要预先规划构建步骤,学习曲线略陡
在实际工作中,Dockerfile 是构建 Docker 镜像的推荐方法,而docker commit通常用于调试和学习过程中。




