Docker 配置详解

目录

  1. Docker 架构
  2. docker-compose.yml 结构
  3. 服务配置详解
  4. 网络配置
  5. 卷配置
  6. 环境变量与配置
  7. 健康检查
  8. 资源限制
  9. 依赖与启动顺序
  10. 生产环境配置

一、Docker 架构

1.1 Docker 核心组件

flowchart TB subgraph Docker_Host[Docker Host] subgraph Containers C1[Container 1] C2[Container 2] C3[Container N] end subgraph Docker_Engine CLI[Docker CLI] API[Docker API] subgraph Daemon D1[Containerd] D2[runc] D3[shim] end end subgraph Storage V1[Volume 1] V2[Volume 2] end subgraph Network N1[bridge] N2[host] N3[overlay] end end User --> CLI CLI --> API API --> Daemon Daemon --> Containers Containers --> Storage Containers --> Network

1.2 Docker vs Docker Compose

组件 说明 使用场景
Docker 单容器管理 快速测试、单个服务
Docker Compose 多容器编排 开发环境、微服务
# Docker 单容器
docker run -d --name nginx -p 80:80 nginx

# Docker Compose 多容器
docker compose up -d

二、docker-compose.yml 结构

2.1 文件版本说明

# v3 是目前最常用的版本
version: "3.8"

services:
  # 服务定义
  my-service:
    image: nginx:latest
    # 服务配置...

networks:
  # 网络定义

volumes:
  # 卷定义

2.2 顶层结构

flowchart TB A[docker-compose.yml] --> B[services] A --> C[networks] A --> D[volumes] A --> E[configs] A --> F[secrets] B --> B1[service1] B --> B2[service2] C --> C1[network1] D --> D1[volume1]

2.3 完整示例

version: "3.8"

services:
  web:
    image: nginx:alpine
    container_name: my-web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - web-data:/var/cache/nginx
    environment:
      - NGINX_HOST=localhost
    networks:
      - frontend
    depends_on:
      - api
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  api:
    build: ./api
    container_name: my-api
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    volumes:
      - ./api:/app
      - /app/node_modules
    networks:
      - backend
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db_password

  db:
    image: postgres:15
    container_name: my-db
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/:ro
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    secrets:
      - db_password

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

volumes:
  db-data:
    driver: local
  web-data:

configs:
  nginx_config:
    file: ./nginx.conf

secrets:
  db_password:
    file: ./secrets/db_password.txt

三、服务配置详解

3.1 image

services:
  # 直接使用镜像
  web:
    image: nginx:latest

  # 私有仓库镜像
  web:
    image: registry.example.com/myapp:v1.0

  # 指定平台
  web:
    image: --platform linux/amd64 nginx:latest

3.2 build

services:
  # 从 Dockerfile 构建
  web:
    build: ./path/to/dockerfile

  # 完整配置
  web:
    build:
      context: ./app          # 构建上下文
      dockerfile: Dockerfile  # Dockerfile 名称
      args:                   # 构建参数
        - VERSION=1.0
        - ENV=production
      target: production      # 多阶段构建目标
      cache_from:             # 缓存来源
        - myapp:cache
      labels:                 # 镜像标签
        - "org.opencontainers.image.source=https://github.com/myapp"
      network: backend        # 构建网络

3.3 ports(端口映射)

services:
  web:
    ports:
      # 格式: "宿主机端口:容器端口"
      - "80:80"
      - "443:443"

      # 指定 IP(仅绑定 localhost)
      - "127.0.0.1:8080:80"

      # UDP 端口
      - "53:53/udp"

      # 随机分配端口
      - "3000"

      # 长格式
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

3.4 volumes(数据卷)

services:
  web:
    volumes:
      # 绑定挂载(相对路径)
      - ./html:/var/www/html

      # 绑定挂载(绝对路径)
      - /host/path:/container/path

      # 命名卷
      - my-volume:/app/data

      # 只读挂载
      - ./config:/app/config:ro

      # 匿名卷(容器内数据不映射到宿主机)
      - /app/cache

      # 长格式
      - type: bind
        source: ./data
        target: /app/data
        read_only: true

3.5 environment(环境变量)

services:
  web:
    environment:
      # 数组格式
      - NODE_ENV=production
      - DEBUG=false

      # 对象格式
      NODE_ENV: production
      DEBUG: "false"

      # 从宿主机环境变量
      - API_KEY=${API_KEY}
      - DB_HOST

      # 带默认值
      - PORT=${PORT:-3000}

3.6 restart(重启策略)

services:
  web:
    # 不自动重启(默认)
    restart: "no"

    # 容器退出时总是重启
    restart: always

    # 容器以非零状态退出时重启
    restart: on-failure

    # 容器以非零状态退出时重启,最多重试 3 次
    restart: on-failure:3

    # 除非手动停止,否则总是重启
    restart: unless-stopped

3.7 command(覆盖默认命令)

services:
  web:
    # 覆盖默认命令
    command: npm start

    # 带参数
    command: ["npm", "start", "--", "--env=production"]

    # 覆盖 ENTRYPOINT
    command: ["python", "-u", "app.py"]

    # Shell 格式
    command: >
      python app.py
      --host 0.0.0.0
      --port 8080

3.8 entrypoint

services:
  web:
    # 覆盖默认 ENTRYPOINT
    entrypoint: ["python", "-u", "app.py"]

    # 禁用默认 ENTRYPOINT
    entrypoint: []

    # 与 command 配合
    entrypoint: ["python"]
    command: ["app.py"]

四、网络配置

4.1 网络类型

flowchart TB A[网络类型] --> B[bridge] A --> C[host] A --> D[overlay] A --> E[none] B --> B1[默认bridge<br/>自定义bridge<br/>容器间通信] C --> C1[跳过Docker网络<br/>直接用宿主机网络] D --> D1[Swarm模式<br/>跨主机通信] E --> E1[无网络<br/>完全隔离]
网络类型 说明 使用场景
bridge 默认桥接网络 单主机容器通信
host 跳过网络命名空间 性能敏感应用
overlay Docker Swarm 网络 多主机通信
none 无网络 离线计算

4.2 自定义网络

services:
  web:
    networks:
      - frontend
  api:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend

networks:
  frontend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
  backend:
    driver: bridge
    internal: true  # 禁止外部访问

4.3 网络别名

services:
  web:
    networks:
      frontend:
        aliases:
          - webapp
          - mywebsite

  api:
    networks:
      frontend:
        aliases:
          - api-server

4.4 端口转发详解

flowchart LR A[宿主机] -->|9092:9092| B[容器 9092] C[其他容器] -->|kafka:9092| B
services:
  kafka:
    ports:
      - "9092:9092"   # 宿主机:容器
    networks:
      backend:

networks:
  backend:
    external: true
    name: services-network

五、卷配置

5.1 卷类型

flowchart TB A[卷类型] --> B[匿名卷] A --> C[命名卷] A --> D[绑定挂载] B --> B1[匿名卷<br/>docker自动生成名称<br/>用于临时数据] C --> C1[命名卷<br/>docker管理<br/>用于持久数据] D --> D1[绑定挂载<br/>宿主机路径映射<br/>用于配置文件]

5.2 卷配置

volumes:
  # 命名卷
  db-data:
    driver: local

  # 自定义配置
  html-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /host/path

  # 标签
  cache:
    labels:
      app: myapp

5.3 数据持久化策略

services:
  db:
    image: postgres:15
    volumes:
      # 命名卷 - 持久化数据
      - postgres-data:/var/lib/postgresql/data

      # 绑定挂载 - 配置文件
      - ./config:/etc/postgresql

      # 只读配置
      - ./init.sql:/docker-entrypoint-initdb.d/:ro

      # 匿名卷 - 临时缓存
      - /tmp/pgdata

volumes:
  postgres-data:

六、环境变量与配置

6.1 env_file

services:
  web:
    env_file:
      - .env
      - .env.local
      - ./config/app.env
# .env 文件内容
NODE_ENV=production
DATABASE_URL=postgres://user:pass@db:5432/myapp
REDIS_URL=redis://cache:6379

6.2 .env 文件变量

# .env
TAG=1.0
IMAGE_NAME=myapp

# docker-compose.yml
services:
  web:
    image: ${IMAGE_NAME}:${TAG}

6.3 敏感信息管理

# 方法1: 使用 .env 文件(不提交到 git)
# .env 文件
DB_PASSWORD=secret123

services:
  web:
    environment:
      - DB_PASSWORD=secret123

# 方法2: 使用 secrets
services:
  web:
    secrets:
      - db_password
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

6.4 变量插值

# 基本变量
${VAR_NAME}

# 带默认值
${VAR_NAME:-default}

# 嵌套变量
${VAR1:-${VAR2:-default}}

# 数组/列表
ports:
  - "${HOST_PORT}:80"

七、健康检查

7.1 healthcheck 配置

services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s           # 检查间隔
      timeout: 10s            # 超时时间
      retries: 3              # 重试次数
      start_period: 40s       # 启动等待时间
      disable: false          # 禁用检查

7.2 常用健康检查命令

# HTTP 检查
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]

# TCP 检查
healthcheck:
  test: ["CMD-SHELL", "pg_isready -h localhost -p 5432 -U postgres"]

# 自定义脚本
healthcheck:
  test: ["CMD", "/usr/local/bin/healthcheck.sh"]
  interval: 30s
  timeout: 10s
  retries: 3

# MySQL 健康检查
healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]

# Redis 健康检查
healthcheck:
  test: ["CMD", "redis-cli", "ping"]

# MongoDB 健康检查
healthcheck:
  test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]

7.3 依赖健康检查

services:
  web:
    depends_on:
      api:
        condition: service_healthy
      db:
        condition: service_started  # 或者 service_healthy

  api:
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]

八、资源限制

8.1 deploy.resources

services:
  api:
    deploy:
      resources:
        limits:
          cpus: '1.5'           # CPU 核心数
          memory: 1G            # 内存限制
          pids: 100            # 进程数限制
        reservations:
          cpus: '0.5'
          memory: 512M

8.2 各类服务推荐配置

# Nginx/Web 服务器
nginx:
  deploy:
    resources:
      limits:
        cpus: '0.5'
        memory: 256M

# Node.js 应用
node-app:
  deploy:
    resources:
      limits:
        cpus: '1.0'
        memory: 512M

# 数据库
postgres:
  deploy:
    resources:
      limits:
        cpus: '2.0'
        memory: 2G

# Java 应用
java-app:
  deploy:
    resources:
      limits:
        cpus: '2.0'
        memory: 1G

8.3 ulimits

services:
  java-app:
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
      nproc:
        soft: 4096
        hard: 4096

九、依赖与启动顺序

9.1 depends_on

services:
  web:
    depends_on:
      - db
      - redis

  api:
    depends_on:
      - db

  db:
    image: postgres:15

  redis:
    image: redis:7

9.2 depends_on + condition

services:
  web:
    depends_on:
      db:
        condition: service_healthy  # 等待健康
      redis:
        condition: service_started # 等待启动

  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]

  redis:
    image: redis:7

9.3 links(已废弃)

# 不推荐使用 links,已被 networks 替代
services:
  web:
    # 旧写法(不推荐)
    links:
      - db
      - redis

    # 新写法(推荐)
    networks:
      - backend

十、生产环境配置

10.1 生产环境模板

version: "3.8"

services:
  app:
    image: ${REGISTRY:-}/myapp:${VERSION:-latest}
    container_name: ${APP_NAME:-myapp}
    restart: always
    ports:
      - "${APP_PORT:-8080}:8080"
    environment:
      - NODE_ENV=production
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - REDIS_HOST=${REDIS_HOST}
      - REDIS_PORT=${REDIS_PORT}
    volumes:
      - app-data:/app/data
      - ./logs:/app/logs
    networks:
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
      rollback_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

  db:
    image: postgres:15-alpine
    container_name: ${DB_NAME:-postgres}
    restart: always
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./backup:/backup
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 2G

  redis:
    image: redis:7-alpine
    container_name: redis
    restart: always
    command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - backend
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 512M

networks:
  backend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.25.0.0/16

volumes:
  app-data:
  db-data:
  redis-data:

10.2 .env 文件示例

# .env.production
REGISTRY=docker.io
VERSION=1.0.0

APP_NAME=myapp
APP_PORT=8080

DB_HOST=db
DB_PORT=5432
DB_NAME=myapp
DB_USER=appuser
DB_PASSWORD=change_me_in_production

REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=change_me_in_production

10.3 多环境配置

# .env.development
NODE_ENV=development
LOG_LEVEL=debug

# .env.staging
NODE_ENV=staging
LOG_LEVEL=info

# .env.production
NODE_ENV=production
LOG_LEVEL=warn
# 使用不同环境
docker compose --env-file .env.development up -d
docker compose --env-file .env.production up -d

附录:docker-compose.yml 完整选项表

服务级别选项

选项 说明 类型
image 镜像名称或 ID string
build 构建配置 object/string
command 覆盖默认命令 string/array
entrypoint 覆盖 ENTRYPOINT string/array
ports 端口映射 array
volumes 数据卷挂载 array
environment 环境变量 array/object
env_file 环境变量文件 array
networks 网络配置 array/object
depends_on 依赖服务 array/object
restart 重启策略 string
healthcheck 健康检查 object
deploy 部署配置 object
container_name 容器名称 string
hostname 主机名 string
privileged 特权模式 boolean
read_only 只读根文件系统 boolean
tmpfs tmpfs 挂载 array/object
user 运行用户 string
working_dir 工作目录 string
expose 暴露端口(不映射到宿主机) array
external_links 链接外部容器 array
links 链接容器(已废弃) array
dns DNS 服务器 array/string
dns_search DNS 搜索域 array
extra_hosts 添加 hosts array/object
labels 容器标签 array/object
ulimits ulimit 配置 object
cap_add 添加 Linux 能力 array
cap_drop 删除 Linux 能力 array
isolation 隔离技术 string
security_opt 安全选项 array

最后更新:2026年4月

posted @ 2026-05-09 10:47  RK5123153  阅读(6)  评论(0)    收藏  举报