Docker

3 阅读13分钟

飞书:qcnk990tpinb.feishu.cn/wiki/LgMgw8…

一、Docker 核心概念

1. 镜像(Image)与容器(Container)

  • 镜像:一个只读模板,包含应用程序、运行环境、配置和依赖库(类似软件安装包),静态不可运行
  • 容器:基于镜像创建的隔离运行环境(镜像的运行实例),动态可读写,容器之间相互独立、互不影响。
  • 关系:一个镜像可以创建多个容器;容器启动后会在镜像上层新增可写层,容器所有数据修改都存在可写层,镜像本身永久不变

2. 镜像仓库

  • 存储和管理镜像的平台,官方公共仓库为 Docker Hub,国内常用阿里云、网易云镜像仓库加速拉取。

二、Docker 客户端与服务端架构

  • Client(客户端):用户执行 docker 命令,发起各类操作请求。
  • Docker Server(服务端):内含 docker daemon 守护进程,负责后台管理镜像、容器、网络、存储。
  • 工作流程:客户端发送命令 → 服务端守护进程处理 → 从镜像仓库拉取镜像 → 创建并启动容器。
  • 补充:采用 C/S 架构,支持远程调用,客户端和守护进程可部署在不同服务器。

三、Docker快速入门-命令解读

以 MySQL 容器启动命令为例:

暂时无法在飞书文档外展示此内容

参数作用
-d后台运行容器(守护进程模式)
--name mysql给容器起唯一名称,便于后续管理
-p 3306:3306端口映射:格式为「宿主机端口:容器端口」,外部可通过宿主机端口访问容器服务
-e TZ=Asia/Shanghai设置容器时区为上海时区,避免容器内时间与本地时间不一致
-e MYSQL_ROOT_PASSWORD=123设置环境变量,配置 MySQL 的 root 用户初始登录密码
-v 宿主机目录:容器目录数据卷挂载,实现数据持久化,容器删除后数据不丢失
--restart always容器开机自启、意外退出后自动重启
mysql:5.7指定要使用的镜像名称和版本号,格式为「镜像名:版本标签」

四、镜像命名规范

  • 公共仓库格式:[repository]:[tag]

    • repository:镜像名称(如 mysql、nginx)
    • tag:镜像版本号(如 5.7、8.0)
  • 私有仓库格式:[仓库地址]/[镜像名]:[版本]

    • 示例:registry.aliyuncs.com/xxx/mysql:5.7
  • 不指定 tag 时,默认使用 latest(最新稳定版),例如 mysql:latest 默认为 MySQL 8.0。

  • 注意:生产环境不建议直接使用 latest 标签,建议指定固定版本号 5.7 / 8.0

五、Docker常见命令


一、镜像仓库与本地镜像交互命令

命令作用场景示例
docker pull 镜像名:tag从镜像仓库(如 Docker Hub)拉取镜像到本地docker pull nginx:latest 拉取最新版 Nginx 镜像
docker push 镜像名:tag将本地构建的镜像推送到镜像仓库docker push my-nginx:v1 把自定义镜像推送到仓库

二、本地镜像构建与管理命令

1. 镜像构建

命令作用场景示例
docker build -t 镜像名:tag .基于当前目录的 Dockerfile 构建自定义镜像docker build -t my-nginx:v1 . 构建含静态资源的 Nginx 镜像

2. 镜像导入导出

命令作用场景示例
docker save -o 文件名.tar 镜像名:tag将本地镜像导出为压缩包(离线传输用)docker save -o nginx.tar nginx:latest
docker load -i 文件名.tar从压缩包导入镜像到本地docker load -i nginx.tar

3. 本地镜像管理

命令作用场景示例
docker images查看本地所有镜像列表快速确认镜像是否拉取/构建成功
docker rmi 镜像名:tag删除本地镜像(需确保无容器依赖该镜像)docker rmi my-nginx:v1

三、容器生命周期与管理命令

1. 容器启停与创建

命令作用场景示例
docker run [参数] 镜像名:tag基于镜像创建并启动容器(核心命令)docker run -d -p 80:80 --name nginx nginx
docker stop 容器名/ID停止运行中的容器docker stop nginx 停止 Nginx 容器
docker start 容器名/ID启动已停止的容器docker start nginx 重启已停止的容器

2. 容器状态查看与删除

命令作用场景示例
docker ps查看当前运行中的容器快速确认容器是否正常启动
docker ps -a查看所有容器(运行中+已停止)排查已停止的容器问题
docker rm 容器名/ID删除已停止的容器docker rm nginx 清理无用容器
docker rm -f 容器名/ID强制删除运行中的容器docker rm -f nginx 强制删除占用端口的容器

3. 容器日志与内部操作

命令作用场景示例
docker logs 容器名/ID查看容器运行日志(排查启动失败/报错)docker logs nginx 查看 Nginx 访问日志
docker exec -it 容器名/ID 命令进入容器内部执行命令(如 bash)docker exec -it nginx bash 进入容器修改配置

四、命令流程总结

  1. 镜像准备:通过 pull/build 获取本地镜像,用 images 查看、rmi 删除,或 save/load 离线传输。
  2. 容器运行:用 run 创建容器,start/stop 控制启停,ps 查看状态。
  3. 容器管理:用 logs 排查问题,exec 进入容器操作,rm 清理容器。
  4. 仓库交互:构建好的镜像可通过 push 推送到仓库,供其他机器拉取使用。

六、数据卷

一、什么是数据卷?

数据卷(Volume)是 Docker 提供的一种文件持久化与容器内外文件同步机制,本质是宿主机上的一个虚拟目录,作为容器内目录 ↔ 宿主机目录之间映射的桥梁。

它解决了两个核心痛点:

  1. 容器删除数据丢失:容器的可写层会随容器删除而销毁,数据卷独立于容器存在,容器删了数据还在。
  2. 容器内文件修改不便:官方镜像通常精简,不预装 vi/vim 等编辑器,直接在宿主机修改数据卷文件即可同步到容器。

二、如何挂载数据卷?

  1. 挂载语法

docker run 创建容器时,使用 -v 参数:

暂时无法在飞书文档外展示此内容

  1. 关键规则

  • 容器创建时,如果挂载的数据卷不存在,Docker 会自动创建该数据卷
  • 容器内的目标目录如果有文件,会被数据卷的内容覆盖(首次挂载时)
  1. 两种常见挂载方式

方式 1:命名数据卷挂载(推荐)

暂时无法在飞书文档外展示此内容

  • 特点:Docker 管理数据卷路径,自动创建,适合通用场景
方式 2:绑定宿主机目录挂载

暂时无法在飞书文档外展示此内容

特点:自定义宿主机路径,需手动创建目录,适合自己管理文件位置。

  • 命名数据卷:Docker 自动管理路径,无需手动建目录
  • 绑定宿主机目录:自定义宿主机路径,目录需手动创建

三、数据卷的底层原理(结合图)

  1. 路径映射关系

  • 容器内路径:图中 Nginx 容器的静态资源目录 /usr/share/nginx/html

  • 数据卷路径:

    • 启动容器时通过 -v html:/usr/share/nginx/html 指定了名为 html 的数据卷
    • Docker 自动在宿主机 /var/lib/docker/volumes/html/_data 下创建对应目录(docker volume inspect html 输出的 Mountpoint 字段可验证)
  • 双向同步:容器内读写 /usr/share/nginx/html 时,实际操作的是宿主机上的 /var/lib/docker/volumes/html/_data 目录;在宿主机修改该目录下的文件,容器内也会同步生效。

  1. 数据卷的生命周期

  • 数据卷的创建、删除独立于容器:创建容器时挂载不存在的数据卷,Docker 会自动创建;删除容器不会自动删除数据卷,需手动执行 docker volume rm
  • 数据卷的文件不会被容器销毁,适合存放数据库数据、日志、静态资源等需要持久化的内容。

四、数据卷核心命令

命令作用常用示例
docker volume create创建数据卷docker volume create html
docker volume ls查看所有数据卷docker volume ls
docker volume inspect查看数据卷详情docker volume inspect html
docker volume rm删除指定数据卷docker volume rm html
docker volume prune清理所有未被使用的数据卷docker volume prune

七、案例

案例一:Nginx 容器数据卷部署静态资源(命名数据卷挂载)

一、案例目标

  1. 创建 Nginx 容器,修改容器内 /usr/share/nginx/html/index.html 静态文件内容
  2. 将本地静态资源部署到 Nginx 容器,实现文件同步与数据持久化

二、核心知识点回顾

  1. 数据卷挂载规则

  • 挂载语法:docker run -v 数据卷名:容器内目录
  • 自动创建:容器启动时,若挂载的数据卷不存在,Docker 会自动创建该数据卷
  • 双向同步:宿主机修改数据卷文件,容器内会实时生效
  1. Nginx 容器静态资源路径

  • 容器内静态文件默认路径:/usr/share/nginx/html
  • 修改该目录下的文件,即可改变 Nginx 对外提供的网页内容

三、完整操作步骤

  1. 准备工作:清理旧容器

暂时无法在飞书文档外展示此内容

  1. 启动 Nginx 容器并挂载数据卷

暂时无法在飞书文档外展示此内容

  • -d:后台守护进程模式运行
  • --name nginx:自定义容器名称
  • -p 80:80:宿主机 80 端口映射容器 80 端口
  • -v html:/usr/share/nginx/html:挂载名为 html 的数据卷到容器静态资源目录
  1. 验证容器与数据卷

暂时无法在飞书文档外展示此内容

  • 输出中的 Mountpoint 字段即为数据卷在宿主机的路径,例如:/var/lib/docker/volumes/html/_data
  1. 修改静态文件(宿主机直接操作)

暂时无法在飞书文档外展示此内容

修改示例:

暂时无法在飞书文档外展示此内容

5.验证效果访问

服务器IP:80 查看页面,修改宿主机文件刷新即可同步。


四、关键验证命令说明

命令作用对应截图中的验证点
docker ps查看容器运行状态确认 Nginx 容器正常启动、端口映射生效
docker volume ls查看所有数据卷验证 html 数据卷已自动创建
docker volume inspect html查看数据卷详情获取数据卷在宿主机的实际路径 Mountpoint

五、避坑与优化说明

  1. 容器内无编辑器问题:官方 Nginx 镜像为精简版,默认不包含 vi/vim,无需进入容器修改,直接在宿主机数据卷目录操作即可。
  2. 文件覆盖问题:首次挂载数据卷时,容器内 /usr/share/nginx/html 的默认文件会被数据卷内容覆盖,需在宿主机数据卷目录中维护文件。
  3. 数据持久化:删除 Nginx 容器不会删除 html 数据卷,数据会永久保留,后续可直接挂载到新容器使用。

案例2 - MySQL 容器数据挂载


一、案例需求

  1. 查看 MySQL 容器,判断是否有数据卷挂载
  2. 基于宿主机目录实现 MySQL 数据目录、配置文件、初始化脚本的挂载(参考官方镜像文档)

二、挂载规则说明

docker run 命令中,使用 -v 参数完成挂载:

  • 绑定宿主机目录-v 本地目录:容器内目录

  • 区分规则

    • /./ 开头 → 被识别为宿主机目录(绑定挂载)
    • 直接以名称开头 → 被识别为数据卷(命名卷)
  • 示例:

    • -v mysql:/var/lib/mysql → 挂载名为 mysql 的数据卷
    • -v ./mysql:/var/lib/mysql → 挂载当前目录下的 mysql 目录

三、挂载目录规划

宿主机目录容器内目录作用
/root/mysql/data/var/lib/mysql挂载 MySQL 数据目录,实现数据持久化
/root/mysql/init/docker-entrypoint-initdb.d挂载 SQL 初始化脚本,容器启动时自动执行
/root/mysql/conf/etc/mysql/conf.d挂载 MySQL 配置文件(如 my.cnf)

四、完整操作步骤

1. 宿主机创建挂载目录

暂时无法在飞书文档外展示此内容

2. 启动 MySQL 容器并挂载目录

暂时无法在飞书文档外展示此内容

3. 验证容器挂载情况

暂时无法在飞书文档外展示此内容

  • 查看 Mounts 字段:Source 宿主机路径、Destination 容器路径、RW 读写权限。

五、关键命令说明

命令作用
docker ps查看 MySQL 容器运行状态
docker inspect mysql查看容器挂载详情,判断是否有数据卷/目录挂载
docker volume ls查看数据卷列表,确认无自动创建的匿名卷

六、避坑说明

  1. 目录权限不足导致 MySQL 启动失败,可临时授权:chmod -R 777 /root/mysql
  2. 初始化 SQL 仅在数据目录为空时执行一次。
  3. 挂载配置文件优先级更高,修改后需重启容器生效。

八、Docker 自定义镜像(Dockerfile)知识点


一、什么是自定义镜像?

镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程,本质就是把上述文件分层打包的过程。


二、Java 应用部署 vs 镜像构建对比


三、镜像分层结构

  • 基础镜像(BaseImage) :提供系统环境、函数库、配置文件(如 Ubuntu 系统)
  • 层(Layer) :每一条 Dockerfile 指令都会生成新的一层(如安装 JRE、拷贝 Jar 包、配置脚本)
  • 入口(Entrypoint) :镜像运行的入口,一般是程序启动命令(如 java -jar xx.jar

四、Dockerfile 核心指令


五、Dockerfile 示例(两种写法)

1. 精简版(基于 JDK 基础镜像)

暂时无法在飞书文档外展示此内容

2. 完整版(基于 Ubuntu 基础镜像)

暂时无法在飞书文档外展示此内容


六、构建镜像命令

暂时无法在飞书文档外展示此内容

  • -t:给镜像打标签,格式 镜像名:版本号,不指定 tag 默认为 latest
  • .:指定 Dockerfile 所在目录(当前目录用 .

七、核心问题解答

  1. 镜像的结构是怎样的?

镜像包含应用运行所需的环境、函数库、配置和应用本身,文件以分层的方式打包存储。

  1. Dockerfile 是做什么的?

用固定指令描述镜像的结构和构建过程,让 Docker 可以按步骤自动构建镜像。

  1. 构建镜像的命令是什么?

docker build -t 镜像名 Dockerfile目录


九、Docker 网络知识点


一、Docker 默认网络(Bridge 模式)

默认情况下,所有容器都通过 bridge 模式连接到 Docker 的虚拟网桥 docker0

  • docker0 网桥默认网段:172.17.0.1/16
  • 每个容器会分配一个独立的虚拟 IP(如 172.17.0.2172.17.0.3
  • 容器内的 eth0 网卡通过 vethX 虚拟设备连接到 docker0 网桥
  • 同一网桥下的容器可通过 IP 互相访问,但无法直接通过容器名访问

二、自定义网络的优势

只有加入自定义网络的容器,才能通过容器名互相访问(内置 DNS 解析),更适合微服务场景。


三、Docker 网络核心命令


四、常用操作示例

1. 创建自定义网络

暂时无法在飞书文档外展示此内容

2. 容器加入自定义网络

暂时无法在飞书文档外展示此内容

3. 查看网络详情

暂时无法在飞书文档外展示此内容