# 🐳 Docker 核心知识与实战笔记 ## 一、 Docker 核心工作流与常用命令速查表 ### 1. 自定义镜像与分享工作流 - **流程**:下载镜像 -> 启动容器 -> 修改页面/配置 -> 保存镜像 (`commit`) -> 导出镜像 (`save`) -> 分享/加载 (`load`) - `docker commit`:将修改后的容器提交为新的本地镜像。 - `docker save`:将镜像保存为 tar 归档文件(用于离线传输)。 - `docker load`:从 tar 归档文件中加载镜像。 ### 2. 常用命令分类速查 (Cheat Sheet) | 分类 | 命令示例 | 功能说明 | | :--- | :--- | :--- | | **镜像 (Image)** | `docker search` | 检索 Docker Hub 上的镜像 | | | `docker pull` | 下载镜像到本地 | | | `docker images` | 列出本地所有镜像 | | | `docker rmi` | 删除本地镜像 | | **容器 (Container)**| `docker run` | 创建并运行一个新容器 | | | `docker ps` | 查看当前正在运行的容器 (`-a` 查看所有) | | | `docker stop` / `start`| 停止 / 启动 容器 | | | `docker restart` | 重启容器 | | | `docker stats` | 查看容器资源实时使用状态 | | | `docker logs` | 查看容器内部日志(排错必备) | | | `docker exec` | 进入正在运行的容器内部执行命令 | | | `docker rm` | 删除已停止的容器 | | **分享与管理** | `docker login` | 登录 Docker 镜像仓库 | | | `docker tag` | 给镜像打标签(重命名,准备推送) | | | `docker push` | 将镜像推送到远程仓库 | --- ## 二、 数据持久化:目录挂载 vs 卷映射 Docker 提供了两种主要的数据持久化方式,通过 `-v` 参数实现: ### 1. 目录挂载 (Bind Mounts) 将宿主机的**绝对路径**直接挂载到容器内。 - **语法**:`-v /宿主机绝对路径:/容器内路径` - **示例**:`-v /app/nghtml:/usr/share/nginx/html` - **特点**:路径完全由用户掌控,适合挂载需要频繁修改的代码或配置文件。 ### 2. 卷映射 (Named Volumes) 由 Docker 自动管理宿主机的存储目录,只需提供一个“卷名”。 - **语法**:`-v 卷名:/容器内路径` - **示例**:`-v ngconf:/etc/nginx` - **底层路径**:Docker 默认会将命名卷存放在宿主机的 `/var/lib/docker/volumes//_data` 目录下。 - **特点**:Docker 统一管理,不用担心宿主机路径权限问题,适合持久化数据库数据等。 ### 3. Volume 常用管理命令 - `docker volume ls`:列出所有由 Docker 管理的卷。 - `docker volume create <卷名>`:提前创建一个数据卷。 - `docker volume inspect <卷名>`:查看卷的详细信息(包含具体的 `Mountpoint` 宿主机物理路径)。 > ⚠️ **排错注意**:在挂载配置文件(如 nginx.conf)时,如果宿主机对应路径下没有该文件,直接挂载会导致容器内部找不到配置文件而启动失败(如截图中 `Exited (1)` 且日志报错 `open() "/etc/nginx/nginx.conf" failed`)。 --- ## 三、 容器网络机制与自定义网络 ### 1. 默认网络 (`docker0`) 的局限性 - Docker 会为每个容器分配一个唯一的内网 IP。 - **痛点**:由于容器重启等原因,**容器的 IP 是动态变化的**。默认的 `docker0` 桥接网络**不支持通过容器名(域名)进行内部互相解析**。 ### 2. 解决方案:创建自定义网络 - **核心优势**:在自定义网络(如命名为 `mynet`)中,**容器名就是稳定的域名**。即使 IP 变了,容器之间依然可以通过容器名互相访问。 ### 3. 实战案例:Redis 主从同步集群(通过容器名通信) 使用自定义网络,让从节点通过主节点的**容器名**进行连接,实现读写分离。 - **Master (主节点 - redis01)**: - 宿主机端口: `6379` - 环境变量: `REDIS_REPLICATION_MODE=master`, `REDIS_PASSWORD=123456` - **Slave (从节点 - redis02)**: - 宿主机端口: `6380` - 环境变量: - `REDIS_REPLICATION_MODE=slave` - `REDIS_MASTER_HOST=redis01` (**重点:直接使用主节点的容器名**) - `REDIS_MASTER_PORT_NUMBER=6379` (主节点内部端口) - `REDIS_MASTER_PASSWORD=123456` - `REDIS_PASSWORD=123456` --- ## 四、 Docker Compose 容器编排 当项目包含多个容器(如 App + MySQL + Redis)时,单个单个 `run` 非常繁琐,此时需要使用 Docker Compose。 ### 1. 核心概念 通过一个 `compose.yaml` (或 `docker-compose.yml`) 声明式文件,一键管理整个项目的多个服务。 ### 2. 常用操作命令 - `docker compose up -d`:**上线**(解析 yaml,创建网络/数据卷,后台启动所有容器)。 - `docker compose down`:**下线**(停止并删除 yaml 中定义的所有容器、网络)。 - `docker compose start [服务名1 服务名2]`:单独启动定义好的服务。 - `docker compose stop [服务名1 服务名2]`:单独停止服务。 - *(扩展)* `docker compose scale <服务名>=<数量>`:对某个服务进行扩缩容(注:新版语法多推荐使用 `up --scale`)。 ### 3. `compose.yaml` 顶级元素构成 编写 yaml 文件时,主要包含以下几个顶级块(Top-level elements): - `name`:项目名称 - `services`:**【核心】** 定义各个服务(如 web, db, cache),每个服务包含镜像、端口映射、环境变量等。 - `networks`:定义项目使用的自定义网络。 - `volumes`:定义项目使用的数据卷。 - `configs`:定义配置信息。 - `secrets`:定义敏感信息(如密码密钥)。 **官方参考文档查阅地址**: `https://docs.docker.com/compose/compose-file/` (编写 yaml 遇到属性不会写时,随时查阅 Reference 官方文档)。