Docker & Docker-Compose 全解析
Docker 是服务容器化、环境一致性、快速部署的核心工具,Docker-Compose 则是多容器微服务编排的标配。以下从核心概念、核心命令、微服务实战配置、高频问题四个维度,整理成可直接落地的指南。
一、核心概念(微服务视角)
1. Docker 核心概念
表格
| 概念 | 微服务场景解释 |
|---|---|
| 镜像(Image) | 微服务的 “安装包”:包含代码、运行时、依赖、配置,只读不可变(如 order-service:v1)。 |
| 容器(Container) | 镜像的运行实例:一个容器对应一个微服务实例(如 inventory-service-1),隔离资源。 |
| 仓库(Registry) | 镜像仓库:存储 / 拉取镜像(Docker Hub 公共仓库、Harbor 私有仓库)。 |
| 网络(Network) | 微服务通信:自定义网络让容器间通过服务名互通(替代 IP,如 order-service 访问 mysql)。 |
| 卷(Volume) | 数据持久化:微服务配置 / 日志 / 数据库数据挂载到宿主机,避免容器销毁数据丢失。 |
2. Docker-Compose 核心概念
表格
| 概念 | 微服务场景解释 |
|---|---|
docker-compose.yml |
多容器编排文件:定义微服务集群(如 order、inventory、mysql、redis 等服务的启动规则)。 |
| 服务(Service) | 对应一个微服务:如 order-service、inventory-service,可配置镜像、端口、依赖、环境变量。 |
| 配置层级 | 优先级:docker-compose.override.yml > docker-compose.yml > 命令行参数(适合多环境)。 |
二、Docker 高频命令清单(微服务开发必备)
1. 镜像操作(核心)
表格
| 命令 | 用途(微服务场景) | 示例 | |
|---|---|---|---|
docker pull <镜像名:版本> |
拉取微服务镜像(如基础镜像、中间件镜像) | docker pull python:3.11-slim / docker pull mysql:8.0 |
|
docker build -t <镜像名:版本> <Dockerfile路径> |
构建微服务镜像 | docker build -t order-service:v1 ./order-service |
|
docker images |
查看本地镜像(排查微服务镜像是否构建成功) | `docker images | grep order-service` |
docker rmi <镜像ID/镜像名> |
删除镜像(清理无用镜像) | docker rmi order-service:v1 / docker rmi -f $(docker images -q)(强制删除所有) |
|
docker tag <原镜像> <新镜像> |
镜像打标签(推送私有仓库前) | docker tag order-service:v1 harbor.example.com/order-service:v1 |
|
docker push <镜像名:版本> |
推送镜像到仓库(团队共享) | docker push harbor.example.com/order-service:v1 |
|
docker save -o <压缩包名> <镜像> |
导出镜像(离线部署) | docker save -o order-service-v1.tar order-service:v1 |
|
docker load -i <压缩包名> |
导入镜像(离线部署) | docker load -i order-service-v1.tar |
2. 容器操作(日常开发 / 调试)
表格
| 命令 | 用途(微服务场景) | 示例 |
|---|---|---|
docker run [参数] <镜像> |
启动单个容器(测试微服务 / 中间件) | docker run -d -p 8000:8000 -v ./app:/app --name order-service order-service:v1 |
常用参数:-d 后台运行-p 端口映射-v 目录挂载--name 容器名--network 自定义网络-e 环境变量 |
微服务启动核心参数 | docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql8 mysql:8.0 |
docker ps |
查看运行中容器(检查微服务是否启动) | docker ps / docker ps -a(包含停止的) |
docker logs <容器名/ID> |
查看容器日志(微服务排错) | docker logs -f order-service(实时日志)/ docker logs --tail 100 order-service(最后 100 行) |
docker exec -it <容器名/ID> <命令> |
进入容器(调试微服务) | docker exec -it order-service bash(进入终端)/ docker exec -it mysql8 mysql -uroot -p(直接执行命令) |
docker start/stop/restart <容器名/ID> |
启停 / 重启容器 | docker restart order-service(微服务配置更新后重启) |
docker rm <容器名/ID> |
删除容器(清理无用容器) | docker rm order-service / docker rm -f $(docker ps -aq)(强制删除所有容器) |
docker inspect <容器名/ID> |
查看容器详情(排查网络 / 挂载问题) | docker inspect order-service(看 IP、挂载路径、环境变量) |
3. 网络 / 卷操作(微服务通信 / 数据持久化)
表格
| 命令 | 用途(微服务场景) | 示例 |
|---|---|---|
docker network create <网络名> |
创建自定义网络(微服务集群通信) | docker network create microservice-network |
docker network ls |
查看网络(确认微服务网络是否存在) | docker network ls |
docker network connect <网络名> <容器名> |
容器加入网络 | docker network connect microservice-network order-service |
docker volume create <卷名> |
创建数据卷(持久化微服务 / 数据库数据) | docker volume create mysql-data |
docker volume ls |
查看数据卷 | docker volume ls |
docker volume inspect <卷名> |
查看卷详情(找挂载路径) | docker volume inspect mysql-data |
三、Docker-Compose 高频命令清单(微服务编排)
1. 基础命令(日常开发)
表格
| 命令 | 用途(微服务场景) | 示例 |
|---|---|---|
docker-compose up |
启动所有微服务(前台运行,看日志) | docker-compose up / docker-compose up -d(后台运行) |
docker-compose up <服务名> |
启动指定微服务(只启动 order-service) | docker-compose up -d order-service |
docker-compose down |
停止并删除所有容器 / 网络(保留卷) | docker-compose down / docker-compose down -v(删除卷,谨慎!) |
docker-compose start/stop/restart |
启停 / 重启所有服务 | docker-compose restart order-service(只重启指定服务) |
docker-compose logs |
查看所有服务日志 |
docker logs --tail 0 容器ID或容器名 只清理某个容器的日志 |
docker-compose ps |
查看编排的容器状态 | docker-compose ps |
docker-compose exec <服务名> <命令> |
进入指定服务容器 | docker-compose exec order-service bash |
docker-compose build |
构建所有服务镜像 | docker-compose build / docker-compose build order-service(只构建指定服务) |
docker-compose pull |
拉取所有服务镜像 | docker-compose pull |
docker-compose config |
验证 yml 文件语法(排错必备) | docker-compose config |
2. 进阶命令(生产 / 调试)
表格
| 命令 | 用途(微服务场景) | 示例 |
|---|---|---|
docker-compose up --scale <服务名>=<数量> |
扩缩容微服务(如启动 3 个 order-service 实例) | docker-compose up -d --scale order-service=3 |
docker-compose -f <自定义yml> up |
指定配置文件(多环境) | docker-compose -f docker-compose.prod.yml up -d(生产环境) |
docker-compose pause/unpause <服务名> |
暂停 / 恢复服务 | docker-compose pause inventory-service(临时暂停库存服务) |
四、微服务实战:docker-compose.yml 模板(可直接复用)
yaml
version: '3.8' # 兼容主流Docker版本
# 自定义网络:所有微服务加入同一网络,通过服务名互通
networks:
microservice-network:
driver: bridge
# 数据卷:持久化数据库/日志数据
volumes:
mysql-data:
redis-data:
app-logs:
services:
# 1. 订单微服务
order-service:
build: ./order-service # 本地构建(也可直接用image)
image: order-service:v1
container_name: order-service
ports:
- "8001:8000" # 宿主机端口:容器端口
- "5679:5678" # 调试端口(debugpy)
volumes:
- ./order-service:/app # 代码挂载(热更新)
- app-logs:/app/logs # 日志持久化
environment:
- PYTHONPATH=/app
- DB_HOST=mysql8 # 直接用服务名访问MySQL
- REDIS_HOST=redis6
depends_on:
- mysql8
- redis6 # 依赖MySQL/Redis,先启动它们
networks:
- microservice-network
command: python -Xfrozen_modules=off -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
# 2. 库存微服务
inventory-service:
build: ./inventory-service
image: inventory-service:v1
container_name: inventory-service
ports:
- "8002:8000"
- "5678:5678"
volumes:
- ./inventory-service:/app
- app-logs:/app/logs
environment:
- DB_HOST=mysql8
- REDIS_HOST=redis6
depends_on:
- mysql8
- redis6
networks:
- microservice-network
command: python -Xfrozen_modules=off -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
# 3. 中间件:MySQL
mysql8:
image: mysql:8.0
container_name: mysql8
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql # 初始化脚本
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=microservice_db
networks:
- microservice-network
restart: always # 异常重启
# 4. 中间件:Redis
redis6:
image: redis:6-alpine
container_name: redis6
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- microservice-network
restart: always
五、微服务开发高频问题 & 解决方案
1. 容器间通信失败
- 原因:未加入同一网络,或用 IP 而非服务名访问。
- 解决:所有服务加入自定义网络,用
depends_on保证启动顺序,访问时用服务名(如mysql8而非172.17.0.2)。
2. 代码挂载后热更新不生效
- 原因:Python/Java 等语言的进程未监听文件变化,或容器内权限不足。
- 解决:
- Python:用
uvicorn --reload(Web 服务)/watchdog监听文件变化; - 权限:挂载时加
:rw(如-v ./app:/app:rw)。
- Python:用
3. 调试端口映射后断点空心
- 原因:
debugpy未监听0.0.0.0,或端口冲突 /pathMappings不匹配。 - 解决:
- 启动命令:
debugpy --listen 0.0.0.0:5678(而非127.0.0.1); - 每个服务调试端口唯一(如 order:5679,inventory:5678)。
- 启动命令:
4. 容器启动后立即退出
- 原因:命令无前台进程(如
python app.py执行完就退出),或日志无权限写入。 - 解决:
- 确保启动命令是前台进程(如 Web 服务
uvicorn app:app --host 0.0.0.0); - 日志目录加权限:
chmod 777 ./logs。
- 确保启动命令是前台进程(如 Web 服务
总结
核心关键点
- Docker 核心:镜像(微服务打包)、容器(运行实例)、网络(服务通信)、卷(数据持久化);
- Docker-Compose 核心:
docker-compose.yml编排多服务,通过depends_on管理依赖,自定义网络保证通信; - 高频命令:开发时用
docker-compose up -d启动集群,logs -f看实时日志,exec进入容器调试,config验证配置语法。
微服务最佳实践
- 镜像轻量化:用
alpine基础镜像,多阶段构建减小体积; - 配置解耦:环境变量 / 配置文件挂载,避免硬编码;
- 日志统一:所有服务日志挂载到宿主机,便于集中收集;
- 调试隔离:每个服务调试端口唯一,避免冲突。
这份清单覆盖微服务开发中 Docker/Compose 的 90% 场景,可直接作为速查手册,遇到问题优先查 docker logs/docker-compose config 定位根因。
参考一:
微服务代码变动后同步到 Docker 的核心逻辑是:让容器感知代码变化,根据「开发环境(需要热更新)」和「生产环境(需要重新构建)」分为两种核心方案,下面从易到难讲解,附实操命令和配置示例。
一、开发环境:代码热更新(无需重启 / 重构镜像)
开发阶段追求「改代码立即生效」,核心是将本地代码挂载到容器内,利用语言 / 框架的热重载特性同步变化,无需重新构建镜像。
1. 核心原理
通过 Docker-Compose 的 volumes 挂载,把本地代码目录映射到容器内的代码目录,容器内运行的服务监听文件变化自动重启。
2. 实操配置(以 Python 微服务为例)
步骤 1:修改 docker-compose.yml(挂载代码 + 启动热重载)
yaml
version: '3.8'
services:
order-service:
build: ./order-service
image: order-service:dev # 开发镜像
ports:
- "8001:8000"
- "5679:5678"
# 核心:本地代码挂载到容器内(覆盖容器原有代码)
volumes:
- ./order-service:/app # 本地代码目录 → 容器内代码目录
- ./order-service/logs:/app/logs # 日志目录单独挂载
environment:
- PYTHONUNBUFFERED=1 # 实时输出日志
# 启动命令:用热重载工具(如 uvicorn --reload)
command: >
python -Xfrozen_modules=off -m uvicorn
app:app
--host 0.0.0.0
--port 8000
--reload # 关键:监听文件变化自动重启
networks:
- microservice-network
步骤 2:验证热更新
- 启动服务:
docker-compose up -d order-service - 修改本地
order-service/app.py代码(比如改接口返回值); - 查看容器日志:
docker-compose logs -f order-service,会看到Reloading Uvicorn日志; - 调用接口,代码修改已生效。
3. 不同语言的热重载配置
表格
| 语言 / 框架 | 热重载工具 / 命令 | 核心配置要点 |
|---|---|---|
| Python (FastAPI/Flask) | uvicorn --reload / flask run --reload | 挂载代码目录,启动命令加 --reload |
| Java (Spring Boot) | spring-boot-devtools | 挂载 target 目录,开启 devtools |
| Node.js (Express) | nodemon | 启动命令:nodemon app.js |
| Go | air (第三方工具) | 挂载代码目录,用 air 启动 |
4. 注意事项
- 权限问题:容器内用户可能没有本地目录写权限,可加
:rw权限:- ./order-service:/app:rw; - 依赖变动:如果改了
requirements.txt/package.json,需重新安装依赖(进入容器执行pip install -r requirements.txt); - 忽略文件:在
.dockerignore中排除__pycache__/node_modules等,避免挂载冲突。
二、测试 / 生产环境:重新构建 + 更新容器
生产 / 测试环境追求稳定性,代码变动后需要重新构建镜像→更新容器,避免热重载带来的性能 / 安全问题。
方案 1:手动更新(单服务)
适合少量服务更新,步骤清晰可控:
bash
运行
# 1. 停止当前服务容器
docker-compose stop order-service
# 2. 重新构建该服务镜像(只构建变动的服务)
docker-compose build order-service
# 3. 重启服务(用新镜像启动)
docker-compose up -d order-service
# (可选)清理旧镜像(避免磁盘占用)
docker image prune -f
方案 2:一键更新(多服务)
适合批量更新多个服务,Docker-Compose 会自动对比镜像哈希,只重构变动的服务:
bash
运行
# 停止服务→重构镜像→启动服务(一键完成)
docker-compose up -d --build
# 只更新指定服务(推荐)
docker-compose up -d --build order-service inventory-service
方案 3:零停机更新(生产环境最佳)
生产环境需要「不中断服务」更新,利用 Docker-Compose 的滚动更新特性:
步骤 1:修改 docker-compose.yml 开启滚动更新
yaml
version: '3.8'
services:
order-service:
build: ./order-service
image: order-service:prod
ports:
- "8001:8000"
deploy:
replicas: 2 # 启动2个实例(保证更新时至少1个可用)
update_config:
parallelism: 1 # 每次更新1个实例
delay: 10s # 间隔10秒更新下一个
failure_action: rollback # 更新失败回滚
monitor: 30s # 监控更新后状态30秒
networks:
- microservice-network
步骤 2:执行零停机更新
bash
运行
# 重构镜像+滚动更新(不中断服务)
docker-compose up -d --build --scale order-service=2 order-service
三、进阶:自动化同步(CI/CD 流水线)
微服务集群规模大时,手动更新效率低,可通过 CI/CD 工具(Jenkins/GitLab CI/GitHub Actions)实现「代码提交→自动构建镜像→自动更新容器」。
示例:GitLab CI 自动化配置(.gitlab-ci.yml)
yaml
stages:
- build # 构建镜像
- deploy # 部署容器
# 构建镜像
build-order-service:
stage: build
script:
- docker build -t order-service:${CI_COMMIT_SHA} ./order-service
- docker tag order-service:${CI_COMMIT_SHA} harbor.example.com/order-service:latest
- docker push harbor.example.com/order-service:latest
# 部署容器(零停机更新)
deploy-order-service:
stage: deploy
script:
- docker-compose pull order-service
- docker-compose up -d --no-build order-service
- docker system prune -f # 清理无用镜像/容器
四、常见问题 & 解决方案
1. 挂载后代码不生效
- 原因:容器内服务未监听文件变化,或挂载路径不匹配;
- 解决:启动命令加热重载参数(如
--reload),检查volumes挂载路径(本地路径和容器路径必须一致)。
2. 重构镜像后容器还是旧代码
- 原因:Docker 缓存了镜像层,未重新构建;
- 解决:构建时加
--no-cache禁用缓存:docker-compose build --no-cache order-service。
3. 生产更新后服务中断
- 原因:单实例更新,没有容灾;
- 解决:开启
deploy.replicas多实例,配合滚动更新配置。
4. 依赖更新后容器内不生效
- 原因:依赖包在镜像构建阶段安装,挂载代码不影响依赖;
- 解决:改了
requirements.txt/pom.xml后,必须重新构建镜像(docker-compose build)。
总结
核心方案对比
表格
| 场景 | 同步方式 | 优点 | 缺点 |
|---|---|---|---|
| 开发环境 | 代码挂载 + 热重载 | 改代码立即生效,效率高 | 仅适合开发,不安全 |
| 测试环境 | 手动 / 一键重构镜像 | 简单可控 | 少量服务中断 |
| 生产环境 | 滚动更新 + 多实例 | 零停机,稳定 | 配置稍复杂 |
| 大规模集群 | CI/CD 自动化流水线 | 全自动化,效率最高 | 需要搭建 CI/CD 环境 |
关键要点
- 开发环境:优先用
volumes挂载 + 热重载,避免重复构建镜像; - 生产环境:必须重构镜像,用滚动更新保证服务不中断;
- 依赖变动:无论哪种环境,改了依赖文件都要重新构建镜像;
- 缓存清理:定期清理旧镜像 / 容器,避免磁盘占用。
根据你的微服务规模选择对应方案,开发阶段用热更新提升效率,生产阶段用滚动更新保证稳定性即可。
更多推荐


所有评论(0)