YAML配置

一、一图速懂

YML 配置
 └── 服务定义 (service)
      ├── 构建生成 → 镜像 (Image)
      │       └── 由 Dockerfile 或 image 指定
      └── 运行生成 → 容器 (Container)
              └── 运行中的实例

二、YAML语法速查表

区块 字段 必选? 说明/建议
顶部 version 可选 新版 Compose 可省略;为兼容老项目可保留 3.8
services 必选 所有容器服务都在这里定义
服务 image 二选一 build 二选一:直接拉镜像
服务 build 二选一 image 二选一:从源码构建镜像
服务 container_name 可选 指定容器名;便于 docker logs/exec
服务 command/entrypoint 可选 覆盖镜像默认启动行为
服务 ports 可选 暴露服务给宿主机/外部;Web 常用
服务 volumes 可选 数据持久化、热更新、加载配置
服务 environment 可选 运行时环境变量(非敏感)
服务 env_file 可选 从文件批量注入环境变量
服务 depends_on 可选 启动顺序/健康依赖(需 healthcheck)
服务 healthcheck 可选(推荐) 让 Compose 感知服务是否健康
服务 restart 可选(推荐) 异常退出自动拉起
服务 networks 可选 放入一个或多个网络(容器内 DNS 解析用服务名)
networks 可选 自定义网络(如需跨服务通信,推荐自定义)
volumes 可选 定义命名卷(用于持久化)
secrets/configs 可选 管理敏感/配置文件(Swarm 更常用)

三、完整 Docker Compose 示例(语法+功能一览)

📄 文件名:docker-compose.yml

# ========= 基础信息 =========
version: "3.8"                       #【可选】Compose 文件语法版本;现代 docker compose 可省略

# ========= 服务定义(核心)=========
services:                             #【必选】所有要运行的容器都放这里

  web:                                #【必选】服务名(自定义):容器内可用此名做 DNS 访问
    # --- 镜像来源(二选一)---
    image: nginx:1.27-alpine         #【可选/二选一】直接用现成镜像
    # build:                         #【可选/二选一】从源码构建镜像;与 image 二选一
    #   context: ./web               #【可选】构建上下文目录(Dockerfile 所在处或其上层)
    #   dockerfile: Dockerfile       #【可选】Dockerfile 文件名(默认就是 Dockerfile)
    #   args:                        #【可选】构建时变量(非运行时)
    #     NODE_VERSION: "20"

    container_name: demo-web         #【可选】指定容器名;不写则按“项目名_服务名_序号”
    hostname: demo-web               #【可选】容器主机名;一般不需要

    # --- 启动命令 ---
    command: ["nginx", "-g", "daemon off;"]  #【可选】覆盖镜像默认 CMD
    # entrypoint: ["sh", "-c"]       #【可选】覆盖 ENTRYPOINT;比 command 更“靠前”

    # --- 端口映射 ---
    ports:                            #【可选】宿主机:容器端口;Web 服务常用
      - "8080:80"                     # 访问 http://localhost:8080 -> 容器 80 端口

    # --- 卷挂载(持久化/热更新)---
    volumes:                          #【可选】
      - ./nginx.conf:/etc/nginx/nginx.conf:ro  #【常用】绑定挂载(宿主机->容器);ro=只读
      - web-static:/usr/share/nginx/html       #【常用】命名卷(由 Docker 管理的持久化)

    # --- 环境变量 ---
    environment:                      #【可选】运行时变量
      - TZ=Asia/Shanghai
      - APP_ENV=production
      # 也可写成字典形式(推荐在需要插值时)
      # APP_ENV: production

    env_file:                         #【可选】从 .env 文件读取变量(不适合放密钥到仓库)
      - ./web.env                     # 文件中形如:KEY=value

    # --- 依赖/启动顺序 ---
    depends_on:                       #【可选】声明依赖;可配健康检查条件
      db:
        condition: service_healthy    # 等 db 健康后再启动(需要 db 定义 healthcheck)

    # --- 健康检查(强烈推荐)---
    healthcheck:                      #【可选】判断服务是否“健康”
      test: ["CMD-SHELL", "wget -qO- http://localhost:80 || exit 1"]
      interval: 30s                   # 间隔
      timeout: 5s                     # 单次超时
      retries: 3                      # 连续失败次数
      start_period: 20s               # 启动宽限期(容器刚启动时不算失败)

    # --- 重启策略 ---
    restart: unless-stopped           #【可选】异常退出自动重启;常用:no/always/unless-stopped

    # --- 网络 ---
    networks:                         #【可选】加入哪些网络
      - app-net

    # --- 资源限制(非 swarm 下本地生效有限,建议仅做提示)---
    # deploy:                         #【可选】主要用于 swarm 模式;本地 compose 大多不生效
    #   resources:
    #     limits:
    #       cpus: "0.50"
    #       memory: 512M

  # ======= 数据库服务示例 =======
  db:
    image: postgres:16-alpine         #【可选/二选一】数据库镜像
    container_name: demo-db
    # security_opt:                   #【可选】安全选项
    #   - no-new-privileges:true
    environment:                      #【强烈建议】设置数据库初始化参数
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: supersecret  # 真实项目不要硬编码,改用 env_file 或 secrets
      POSTGRES_DB: appdb
      TZ: Asia/Shanghai
    volumes:
      - db-data:/var/lib/postgresql/data  #【强烈建议】持久化数据库数据
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro  # 初始化脚本(可选)
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] # $$转义$
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    ports:                             #【可选】若需要外部工具连 DB
      - "5432:5432"
    restart: unless-stopped
    networks:
      - app-net

  # ======= 后端服务示例(与 web/db 同网)=======
  api:
    build:
      context: ./api                  #【可选/二选一】从源码构建
      dockerfile: Dockerfile
    container_name: demo-api
    environment:
      APP_ENV: production
      DB_HOST: db                     # 直接用服务名做主机名(因在同一网络)
      DB_PORT: "5432"
      DB_USER: appuser
      DB_PASS: supersecret
      DB_NAME: appdb
    volumes:
      - ./api:/app:rw                 # 代码热更新(开发期用;生产建议只用镜像)
    ports:
      - "3001:3001"
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - app-net

# ========= 网络定义 =========
networks:
  app-net:                            #【可选】自定义网络名称
    driver: bridge                    #【可选】默认 bridge;多数场景够用

# ========= 卷定义(命名卷)=========
volumes:
  db-data:                            #【可选】命名卷,用于数据库等数据持久化
    driver: local
  web-static:                         #【可选】命名卷,用于静态资源持久化
    driver: local

# =========(可选)Secrets/Configs(更安全的配置方式,Swarm 更常用)=========
# secrets:
#   db_password:                      # 把敏感信息放到本地文件,避免进仓库
#     file: ./secrets/db_password.txt
# configs:
#   nginx_conf:
#     file: ./nginx.conf

示例二

version: '3.8'

services:
  sleep-checkin:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: sleep-checkin-app
    ports:
      - "3001:3001"
    volumes:
      # 持久化数据库文件
      - ./data:/app/data
      # 可选:挂载日志目录
      - ./logs:/app/logs
    environment:
      - NODE_ENV=production
      - PORT=80
      - JWT_SECRET=sleep-checkin-secret-key-2025
      - FRONTEND_URL=http://example.com
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    networks:
      - sleep-checkin-network

networks:
  sleep-checkin-network:
    driver: bridge

volumes:
  # 命名卷用于数据持久化(可选)
  sleep-checkin-data:
    driver: local