第18章 Docker Compose基础

从本章开始进入Compose主题。Compose让我们用一个docker-compose.yml文件定义多容器应用,统一启动、停止和管理。

18.1 Compose是什么

18.1.1 为什么需要Compose

多容器应用通常包含:

  • Web前端
  • API服务
  • 数据库
  • 缓存

如果每个服务都用docker run启动,配置复杂且难以复现。Compose可以:

一键启动/停止

统一配置

可移植

便于团队协作

18.1.2 Compose核心概念

text 复制代码
Compose核心概念:

Project(项目)
  ├── Service(服务)
  │     └── Container(容器)
  └── Network / Volume
  • Project:当前目录的compose工程
  • Service:一个应用组件,通常对应一个容器
  • Container:服务的运行实例

18.2 Compose安装与版本

18.2.1 Compose v2(推荐)

Docker Desktop默认包含Compose v2(作为Docker插件)。

bash 复制代码
# 查看版本
docker compose version

# 输出示例:
# Docker Compose version v2.x.x

18.2.2 Compose v1(已弃用)

旧版命令为docker-compose,已进入维护模式:

bash 复制代码
docker-compose version

建议 :使用docker compose(有空格)。

18.3 docker-compose.yml结构

18.3.1 最小示例

yaml 复制代码
version: '3.8'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"

18.3.2 完整结构

yaml 复制代码
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=example.com
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - db

  db:
    image: postgres:13
    environment:
      - POSTGRES_PASSWORD=secret
    volumes:
      - db-data:/var/lib/postgresql/data

networks:
  default:
    driver: bridge

volumes:
  db-data:

18.4 常用字段详解

18.4.1 image / build

yaml 复制代码
services:
  app:
    image: myapp:1.0

  api:
    build:
      context: ./api
      dockerfile: Dockerfile

18.4.2 ports

yaml 复制代码
services:
  web:
    ports:
      - "8080:80"
      - "443:443"

18.4.3 environment 与 env_file

yaml 复制代码
services:
  app:
    environment:
      - DEBUG=true
      - APP_ENV=dev
    env_file:
      - .env

18.4.4 volumes

yaml 复制代码
services:
  app:
    volumes:
      - ./src:/app/src
      - app-data:/app/data

volumes:
  app-data:

18.4.5 networks

yaml 复制代码
services:
  app:
    networks:
      - frontend
      - backend

networks:
  frontend:
  backend:
    internal: true

18.4.6 depends_on

yaml 复制代码
services:
  app:
    depends_on:
      - db
      - redis

⚠️ depends_on只保证启动顺序,不保证服务就绪。

18.5 Compose常用命令

bash 复制代码
# 启动(前台)
docker compose up

# 启动(后台)
docker compose up -d

# 停止
docker compose stop

# 停止并删除容器、网络
docker compose down

# 停止并删除容器、网络和volume
docker compose down -v

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs

# 查看单个服务日志
docker compose logs -f web

# 进入容器
docker compose exec web sh

# 重建镜像
docker compose build

18.6 环境变量与配置管理

18.6.1 .env文件

bash 复制代码
# .env
APP_ENV=dev
DB_PASSWORD=secret
yaml 复制代码
services:
  db:
    image: postgres
    environment:
      - POSTGRES_PASSWORD=${DB_PASSWORD}

18.6.2 变量优先级

  1. docker compose命令行-e
  2. shell环境变量
  3. .env文件
  4. compose文件内的默认值

18.6.3 多环境配置

yaml 复制代码
# docker-compose.override.yml
services:
  app:
    environment:
      - DEBUG=true
    volumes:
      - ./src:/app/src
bash 复制代码
# 默认会自动合并 override 文件
docker compose up

18.6.4 多个配置文件

bash 复制代码
# 指定多个文件(后者覆盖前者)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

18.7 实战:本地开发环境

18.7.1 Node.js + PostgreSQL

yaml 复制代码
version: '3.8'
services:
  app:
    image: node:18
    working_dir: /app
    volumes:
      - ./app:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    command: npm run dev
    environment:
      - NODE_ENV=development
    depends_on:
      - db

  db:
    image: postgres:13
    environment:
      - POSTGRES_PASSWORD=secret
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

18.7.2 Python + Redis

yaml 复制代码
version: '3.8'
services:
  api:
    image: python:3.11
    working_dir: /app
    volumes:
      - ./api:/app
    ports:
      - "8000:8000"
    command: sh -c "pip install -r requirements.txt && python app.py"
    depends_on:
      - redis

  redis:
    image: redis:7.0

18.8 常见问题

18.8.1 端口冲突

bash 复制代码
# 查看端口占用
sudo lsof -i :3000

# 修改compose端口映射
ports:
  - "3001:3000"

18.8.2 容器反复重启

bash 复制代码
# 查看日志
docker compose logs app

# 进入容器检查
docker compose exec app sh

18.8.3 depends_on不能保证就绪

解决方案:使用健康检查。

yaml 复制代码
services:
  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  app:
    depends_on:
      db:
        condition: service_healthy

18.9 Compose最佳实践

text 复制代码
✅ 以服务划分compose文件
✅ 使用.env管理配置
✅ 开发/生产使用不同compose文件
✅ 合理使用volume持久化
✅ 使用healthcheck保证服务就绪
✅ 将敏感配置放在外部(环境变量/secret)
✅ 使用profiles控制可选服务

18.9.1 使用profiles

yaml 复制代码
services:
  app:
    image: myapp

  debug:
    image: alpine
    profiles: ["debug"]
bash 复制代码
# 仅启动debug profile
docker compose --profile debug up

18.10 小结

通过本章学习,我们掌握了Compose基础:

✅ Compose核心概念与优势

✅ docker-compose.yml结构

✅ 常用字段详解(image/build/ports/env/volumes/networks)

✅ 常用命令(up/down/logs/exec/build)

✅ 环境变量与多环境配置

✅ 实战示例(Node.js+Postgres、Python+Redis)

✅ 常见问题与最佳实践

下一步

在第19章中,我们将学习Compose进阶:

  • 多容器依赖与健康检查
  • Compose扩展语法
  • 资源限制与部署策略
  • Compose与CI/CD结合

本章思考题

  1. Compose解决了哪些多容器管理问题?
  2. depends_onhealthcheck的区别是什么?
  3. 为什么要区分开发与生产compose文件?
  4. .envenv_file的区别是什么?
  5. 如何用profiles控制可选服务启动?

相关资源

相关推荐
dreams_dream2 小时前
docker清除所有网络
运维·docker·容器
呆萌的代Ma2 小时前
N8N(一):在Docker中安装N8N
docker·容器·n8n
only_Klein3 小时前
Kubernetes-StatefulSet控制器
云原生·容器·kubernetes
一条闲鱼_mytube15 小时前
Kubernetes Operator 原理与实践:从入门到实战
云原生·容器·kubernetes
DeeplyMind16 小时前
第6章 Docker镜像基础操作
运维·docker·容器
马丁的代码日记17 小时前
Docker 无法拉取镜像的解决方案
运维·docker·容器
是小王吖!17 小时前
容器技术 - docker
运维·docker·容器
Cyber4K18 小时前
【Kubernetes专项】Ingress、Ingress-Controller
云原生·容器·kubernetes
礼拜天没时间.1 天前
Docker与Harbor迁移实战:从入门到生产级完整指南
linux·运维·docker·容器·架构·centos