文章目录
- 前言
- 理论部分
-
- 8_镜像的创建
-
- [8.1_Docker 镜像结构](#8.1_Docker 镜像结构)
- [8.2_Dockerfile 指令详解](#8.2_Dockerfile 指令详解)
- 8.3_镜像三种创建方式
- 实验部分
-
- 8_Dockerfile构建Apache镜像
-
- 8.1_准备工作
-
- [① 网站页面](#① 网站页面)
- [② 启动脚本(按需)](#② 启动脚本(按需))
- 8.2_编写Dockerfile
-
- [① 主体部分](#① 主体部分)
- [② 启动部分](#② 启动部分)
- 8.3_构建和运行
-
- [① 构建镜像](#① 构建镜像)
- [② 运行容器](#② 运行容器)
- [③ 测试访问](#③ 测试访问)
- 结语
前言
本文系统梳理 Docker 镜像创建,涵盖理论原理、操作命令、配置文件路径、端口设置、构建流程与部署细节。
- Dockerfile 详解
- 分层机制
- 构建命令
理论部分
8_镜像的创建
Docker镜像通过分层方式构建并复用缓存,运行时在镜像之上独立建立容器读写层,并通过写时复制机制实现高效隔离和复用。
- Docker 镜像是一个特殊的只读文件系统,包含容器运行所需的程序、库、资源、配置及运行时参数(如环境变量、用户、匿名卷等),但不包含动态数据。
- 镜像采用分层结构,底层共享宿主机 kernel,仅需提供 rootfs(根文件系统),因此如 CentOS 镜像可精简至约 200MB。
- 镜像定制的核心方式是编写 Dockerfile,通过脚本化指令实现透明、可复用、自动化的镜像构建。
8.1_Docker 镜像结构
镜像分层机制:
- 镜像由多层 read-only 的 rootfs 构成,每层对应 Dockerfile 中的一条指令。
- 容器启动时,在镜像最上层叠加一个 read-write 层,所有文件修改均写入此层。
- 删除容器时,仅删除该 read-write 层,底层镜像不变。
镜像缓存规则:
- 每条 Dockerfile 指令生成一个镜像层,并被缓存复用。
- 若某层指令、复制文件或构建变量发生变化,则该层及之后所有层缓存失效。
- 镜像层不可变:若某层添加文件,下一层删除,该文件仍存在于镜像中,仅在容器中不可见。
宿主机 Kernel
bootfs 共享
rootfs Layer 1: 基础 OS
rootfs Layer 2: 软件安装
rootfs Layer 3: 配置文件
Read-Write Container Layer
8.2_Dockerfile 指令详解
Dockerfile 结构四部分:
- 基础镜像信息(FROM)
- 维护者信息(MAINTAINER)
- 镜像操作指令(RUN、ADD、COPY 等)
- 容器启动指令(CMD、ENTRYPOINT)
常用指令列表:
FROM:指定基础镜像,必须为第一行MAINTAINER:指定维护者信息RUN:执行命令并提交到镜像层CMD:容器启动默认命令,可被docker run覆盖ENTRYPOINT:容器启动主命令,参数由CMD提供,不会被run覆盖。优先级:docker run>ENTRYPOINT>CMDEXPOSE:声明容器监听端口ENV:设置环境变量,Linux的PATH=也可以设置环境变量。ADD:复制文件/目录,支持 URL 下载和自动解压COPY:仅复制本地文件/目录VOLUME:创建挂载点USER:设置运行用户WORKDIR:设置工作目录ONBUILD:作为基础镜像时触发的指令(例如防盗用镜像)HEALTHCHECK:设置健康检查命令
Dockerfile 编写规范:
- 第一行必须为
FROM - 推荐第二行为
MAINTAINER - 中间为镜像操作指令(每条新增一层)
- 最后使用
CMD或ENTRYPOINT指定启动命令
8.3_镜像三种创建方式
- 基于现有镜像创建:修改容器后
docker commit - 基于本地模板创建:
docker import导入 tar 包 - 基于 Dockerfile 创建:
docker build(推荐)
实验部分
8_Dockerfile构建Apache镜像
8.1_准备工作
① 网站页面
shell
mkdir /opt/apache && cd /opt/apache
echo "this is test web" > index.html
② 启动脚本(按需)
shell
vim run.sh
bash
#!/bin/bash
rm -rf /run/httpd/*
/usr/sbin/apachectl -D FOREGROUND
rm -rf /run/httpd/*:清理 httpd 运行时缓存
apachectl -D FOREGROUND:前台运行,确保 PID 1 进程持续,容器不退出
8.2_编写Dockerfile
① 主体部分
shell
vim Dockerfile
dockerfile
# 基于的基础镜像
FROM centos:7
# 维护镜像的用户信息
MAINTAINER this is apache image <dockerfile@topen.top>
# 清空yum源配置文件及缓存
RUN rm -f /etc/yum.repos.d/*
# 添加yum镜像源
ADD https://mirrors.aliyun.com/repo/Centos-7.repo /etc/yum.repos.d/
ADD https://mirrors.aliyun.com/repo/epel-7.repo /etc/yum.repos.d/
# 刷新yum缓存
RUN yum clean all && yum makecache
# 镜像操作指令安装apache软件
RUN yum -y install httpd
# 开启 80端口
EXPOSE 80
EXPOSE 443
# 复制网站首页文件
ADD index.html /var/www/html/index.html
② 启动部分
- 方法一:使用CMD+参数直接启动(最常用)
shell
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
对于Apache这类单一服务,
CMD ["httpd", "-D", "FOREGROUND"]最简洁直接,是绝大多数场景的首选。
- 方法二:ENTRYPOINT+CMD(更灵活)
shell
ENTRYPOINT [ "/usr/sbin/apachectl" ]
CMD ["-D", "FOREGROUND"]
组合使用能将命令与参数分离,适合需要支持多种运行参数、让镜像变身"黑盒工具"的场景。
- 方法三:使用run.sh启动脚本(最强大但复杂)
dockerfile
# 将脚本复制到镜像
ADD run.sh /run.sh
RUN chmod 755 /run.sh
# 启动容器时执行脚本
CMD ["/run.sh"]
通过
CMD ["/run.sh"]调用脚本能处理任何复杂初始化逻辑,但增加了维护成本,仅在简单方法无法满足需求时使用。
8.3_构建和运行
① 构建镜像
shell
docker build -t httpd:centos .
-t:指定镜像名称和标签
.:表示 Dockerfile 所在当前目录
② 运行容器
shell
docker run -d -p 8083:80 httpd:centos
-d:后台运行
-p 8083:80:将宿主机 1216 端口映射到容器 80 端口
③ 测试访问
shell
curl http://192.168.10.23:1216/
结语
镜像分层 :每条 Dockerfile 指令生成一层,缓存机制提升构建效率
前台运行:容器内主进程必须前台运行(PID 1),否则容器退出
!question\] 为什么 Docker 中的 CentOS 镜像只有 200MB? 因为镜像只需提供 rootfs(基本命令、工具、库),底层直接复用宿主机 kernel,无需包含 bootfs。 \[!question\] Dockerfile 中 ADD 和 COPY 有什么区别? ADD 支持 URL 下载和自动解压 tar.gz 等归档文件;COPY 仅复制本地文件,更透明安全。 \[!question\] 容器运行后修改了文件,删除容器后文件还在吗? 不在。所有修改写入顶层 read-write 层,删除容器即删除该层,修改丢失。