第3章 编写第一个 docker-compose.yml:服务定义、镜像选择、端口映射、卷挂载、环境变量

3.1 原理概述

docker-compose.yml 是 Docker Compose 的核心配置文件,它以 YAML 格式声明一组多容器应用的服务定义、网络、卷以及运行时参数。每条 service 本质是对 docker run 命令的抽象,通过声明式语法实现可重复、可版本管理的环境装配。

本章聚焦四个必配要素:

  • 服务定义(services:)—— 容器编排的最小单元
  • 镜像选择(image:)—— 决定运行时依赖
  • 端口映射(ports:)—— 对外暴露服务入口
  • 卷挂载(volumes:)—— 数据持久化与热更新
  • 环境变量(environment:)—— 注入配置参数
学习目标:手写一份能启动 Nginx + Redis 测试环境的 Compose 文件,并验证端口、日志与数据目录的挂载效果。

3.2 实现流程

  1. 在项目根目录创建 docker-compose.yml
  2. 定义服务名称(如 web、cache)
  3. 选择官方镜像并指定版本标签
  4. 配置端口映射:宿主机端口:容器端口
  5. 配置卷挂载:宿主机路径:容器路径
  6. 添加环境变量键值对
  7. 执行 docker compose up -d 启动验证

3.3 核心配置详解

3.3.1 服务定义与镜像选择

每个服务以顶层 key 声明,image 字段指定可用的镜像仓库与标签。

services:
  web:
    image: nginx:1.25-alpine
  cache:
    image: redis:7.2-alpine
镜像选择策略对照
策略 示例 适用场景
指定小版本 nginx:1.25.3 生产环境固定版本
使用滚动标签 nginx:latest 本地快速试验
Alpine 精简版 redis:7-alpine 节省镜像体积 & CI 环境
自定义构建镜像 build: ./app 需要定制 Dockerfile

3.3.2 端口映射

格式:宿主机IP:宿主机端口:容器端口(IP 可省略)。

services:
  web:
    image: nginx:1.25-alpine
    ports:
      - "8080:80"          # 宿主机所有IP的8080→容器80
      - "127.0.0.1:8081:80" # 仅绑定本地回环
常见错误:若同时启动多个服务映射相同宿主机端口,Compose 会报 port is already allocated。请确保端口唯一。

3.3.3 卷挂载

支持命名卷(由 Compose 管理)与绑定挂载(直接映射宿主机路径)。

services:
  web:
    image: nginx:1.25-alpine
    volumes:
      - ./html:/usr/share/nginx/html   # 绑定挂载,用于静态文件热更
  cache:
    image: redis:7.2-alpine
    volumes:
      - redis-data:/data               # 命名卷,持久化数据

volumes:
  redis-data:                          # 顶层声明命名卷

3.3.4 环境变量

使用 environment 或 env_file 注入配置。

services:
  cache:
    image: redis:7.2-alpine
    environment:
      - REDIS_PASSWORD=mysecret
      - REDIS_MAXMEMORY=256mb

3.4 完整示例:Nginx + Redis 测试环境

将以上要素整合为一份可运行的 Compose 文件:

version: "3.9"
services:
  web:
    image: nginx:1.25-alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
  cache:
    image: redis:7.2-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    environment:
      - REDIS_PASSWORD=devpass

volumes:
  redis-data:
docker-compose.yml 核心结构 docker-compose.yml services: 服务定义 image: 镜像选择 ports: 端口映射 volumes: 卷挂载 environment 环境变量 服务定义子属性 - build - depends_on - networks 端口映射格式 "宿主机:容器" "IP:宿主机:容器" 容器端口暴露 卷挂载形式 命名卷: /data 宿主路径:容器路径 相对/路径

3.5 调试与验证

启动服务后,使用以下命令验证配置是否生效:

# 启动所有服务(后台)
docker compose up -d

# 查看服务状态
docker compose ps

# 查看运行日志(实时追踪 web 服务)
docker compose logs -f web

# 验证端口映射(从宿主机访问)
curl -I http://localhost:8080

# 检查卷挂载是否写入
echo "Hello from bind mount" | tee ./html/index.html
curl http://localhost:8080/index.html

3.6 常见错误与稳定性建议

错误场景 典型提示 解决方案
端口被占用 port is already allocated 检查 netstat -tulpn,更换宿主机端口
镜像拉取失败 manifest for ... not found 确认镜像标签存在;使用 docker pull 测试
卷挂载权限拒绝 Permission denied 宿主机目录加 chmod 755 或使用 :Z SELinux 标签
环境变量未生效 容器内 printenv 无变量 检查缩进;使用 env_file 代替内联
性能与稳定性优化:
- 避免使用 latest 标签在反复环境下引入不可控更新;
- 绑定挂载适合开发,生产环境优先使用命名卷;
- 敏感变量(密码、)不要直接写在 YAML 中,使用 .env 文件或 Docker Secrets。

3.7 本章小结

通过手写第一份 docker-compose.yml,你已经掌握了声明式服务编排的四个核心要素:镜像选择、端口映射、卷挂载、环境变量。配合调试命令 docker compose up -d、logs、ps,可以快速验证配置正确性。接下来的章节将在此基础上添加网络、依赖控制与多环境部署。