源本科技 | 码上会

Docker Compose

2025/12/24
146
0

学习目标

通过本课件,你将掌握:

  1. Docker Compose 的核心价值:解决多容器应用的复杂性;

  2. docker-compose.yml 文件结构与关键字段详解

  3. 服务(Services)、网络(Networks)、卷(Volumes)的配置技巧

  4. 环境变量管理的最佳实践

  5. 常用命令速查表与故障排查方法。


为什么需要 Docker Compose

多容器手动管理的痛点

问题

描述

命令冗长

每个 docker run 需指定 -p, -v, --network, --env 等,易出错

网络脆弱

容器 IP 动态分配,硬编码导致通信失败

不可复现

“在我机器上能跑” → 开发、测试、生产环境不一致

启动顺序混乱

数据库未就绪,Web 应用已启动 → 连接失败

Compose 的解决方案

声明式编排:只需一个 docker-compose.yml 文件,定义整个应用栈,Docker Compose 自动处理:

  • 容器创建与依赖顺序

  • 内部 DNS 解析(服务名 = 主机名)

  • 网络隔离与互联

  • 数据持久化

  • 一键启停

一句话总结“用 YAML 描述你的应用,让 Docker Compose 负责运行它。”


核心结构

version: '3.8'          # Compose 文件格式版本(推荐 3.x)

services:               # 定义所有服务(每个服务 = 一个容器)
  web:
    image: nginx:latest
    ports:
      - "80:80"
    networks:
      - frontend
    volumes:
      - shared-data:/usr/share/nginx/html
    depends_on:
      - app

  app:
    build: ./my-app     # 或使用 image: my-app:latest
    command: python app.py
    networks:
      - frontend
    volumes:
      - shared-data:/app/data

networks:               # 自定义网络(可选)
  frontend:
    driver: bridge

volumes:                # 声明命名卷(可选)
  shared-data:

核心组件详解

Services

每个服务对应一个容器,支持以下关键配置:

配置项

作用

示例

image

使用现有镜像

image: postgres:13

build

从本地 Dockerfile 构建

build: ./backend

ports

端口映射(主机: 容器)

ports: ["5000:5000"]

volumes

挂载卷或绑定挂载

volumes: [db_data:/var/lib/postgresql/data]

environment

设置环境变量

environment: ["DB_HOST=db", "DEBUG=1"]

env_file

从文件加载环境变量

env_file: .env

depends_on

启动依赖(仅控制顺序,不等待就绪)

depends_on: [db]

command

覆盖默认启动命令

command: ["npm", "start"]

注意:depends_on 不保证服务已完全就绪(如数据库完成初始化)。需配合健康检查或应用重试机制。


Networks

  • 默认行为:所有服务自动加入一个默认网络,可通过服务名互相访问(如 http://db:5432)。

  • 自定义网络:用于隔离或精细控制通信。

示例:前后端分离网络

services:
  web:
    image: nginx
    networks:
      - frontend   # 对外暴露
      - backend    # 访问数据库

  db:
    image: postgres
    networks:
      - backend    # 仅内部访问

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.16.238.0/24

优势:数据库 (db) 无法从外部直接访问,提升安全性。


Volumes

确保容器重启 / 删除后数据不丢失。

类型

说明

示例

命名卷(Named Volume)

Docker 管理,路径抽象

volumes: [db_data:/var/lib/postgresql/data]

绑定挂载(Bind Mount)

直接映射主机目录

volumes: [/host/path:/container/path]

tmpfs

内存临时存储

tmpfs: /tmp

高级配置(使用 driver_opts 实现绑定挂载)

volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/myapp/db

安全建议:敏感数据(如数据库文件)应使用命名卷或受控的绑定挂载,避免随意暴露主机目录。


环境变量管理

方法一:内联定义(适合少量变量)

environment:
  - DB_USER=admin
  - DB_PASS=secret

方法二:外部 .env 文件(推荐!)

env_file:
  - .env

.env 文件内容:

DB_USER=admin
DB_PASS=secret
API_KEY=xyz123

优势

  • 敏感信息不写入代码仓库(记得加 .env.gitignore

  • 不同环境(dev/staging/prod)只需切换 .env 文件


常用命令速查

命令

作用

示例

docker-compose up

启动所有服务

docker-compose up -d(后台运行)

docker-compose down

停止并移除容器、网络、卷

docker-compose down -v(同时删除卷)

docker-compose ps

查看服务状态

docker-compose logs

查看日志

docker-compose logs -f web(实时跟踪)

docker-compose exec

进入运行中的容器

docker-compose exec db psql

docker-compose build

重新构建镜像

docker-compose build --no-cache

docker-compose config

验证 YAML 语法

docker-compose config

docker-compose restart

重启服务

docker-compose restart web


最佳实践

  1. 版本控制:始终指定 version: '3.8'(避免兼容性问题);

  2. 不要硬编码敏感信息:使用 .env 文件 + env_file

  3. 开发 vs 生产

    • 开发:使用 volumes 绑定挂载实现代码热更新;

    • 生产:使用构建好的镜像,避免挂载源码;

  4. 健康检查:对于关键服务(如数据库),添加 healthcheck 确保真正就绪后再启动依赖服务;

  5. 资源限制:在生产环境中使用 deploy.resources 限制 CPU/ 内存(需 Swarm 模式)。


总结

  • Docker Compose = 多容器应用的“一键启动器”

  • YAML 文件 = 应用的“蓝图”,声明服务、网络、存储;

  • 服务名 = 内部 DNS 主机名,无需 IP;

  • .env 文件 + env_file = 安全配置管理

  • docker-compose up/down = 开发调试的黄金组合


思考题

  1. depends_on 能否确保数据库完全初始化完成?如果不能,如何解决?

  2. 在生产环境中,是否应该使用绑定挂载(bind mount)来挂载应用代码?为什么?

  3. 如何在一个 Compose 文件中为不同环境(dev/staging/prod)定义不同配置?


📘 延伸阅读