Files
zhuangang/topics/devops/docker/02-compose-network-volume.md
T

3.9 KiB
Raw Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
id title type domain stack tags level prerequisites est_hours related week order
devops.docker.compose-network-volume Compose、网络和数据卷:多服务编排、健康检查、环境变量 lesson devops
docker
Compose
网络
数据卷
健康检查
环境变量
basic
devops.docker.image-dockerfile
2
devops.docker.scenario.compose-dev-env
devops.docker.interview
3
6
13
2

Compose、网络和数据卷:多服务编排、健康检查、环境变量

解释说明

  • Compose:用一个 compose.yaml 描述多个服务(应用、数据库、缓存),docker compose up -d 一起启动。适合本地开发、测试环境和小规模单机部署;多机、大规模用 Kubernetes。
  • 网络:Compose 默认为项目创建一个网络,服务之间用服务名当主机名访问(db:5432),不需要知道 IP。容器内的 localhost 指的是容器自己,不是宿主机。
  • 端口映射:ports: "8080:8080" 是“宿主机端口:容器端口”,只有需要从宿主机访问的服务才映射。数据库不映射端口更安全(只在内部网络可见)。
  • 数据卷:容器删除后可写层的数据就没了。数据库数据要放在命名卷(Docker 管理)或绑定挂载(宿主机目录,开发时挂源码目录方便热更新)。
  • 健康检查和启动顺序:depends_on 默认只保证“先启动”,不保证“已就绪”。给数据库配 healthcheck,应用用 condition: service_healthy 等待。应用本身也要有连接重试。
  • 环境变量:environment 直接写,或 env_file: .env;.env 文件不要提交到 Git。Compose 文件里 ${VAR} 会从 shell 或项目目录的 .env 读取。

常用命令:docker compose up -d --build、docker compose ps、docker compose logs -f api、docker compose exec db psql -U app、docker compose down(加 -v 会删除数据卷,小心)。

案例

开发 RAG 服务时需要 PostgreSQL(含 pgvector)+ Redis + 应用。用 Compose:新同事 clone 仓库后 docker compose up -d 就能跑;数据库数据存在命名卷里,重启不丢;db 不映射端口,需要调试时临时 docker compose exec db psql。

代码示例

完整文件见 examples/go-api-compose/compose.yaml:

services:
  api:
    build: .
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:app@db:5432/app?sslmode=disable   # 用服务名 db 访问
      REDIS_URL: redis://redis:6379/0
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

易错点

  • 应用里连 localhost:5432:在容器里 localhost 是应用容器自己,要用服务名 db。
  • 以为 depends_on 会等数据库就绪:只等容器启动。要配健康检查,应用也要能重试连接。
  • docker compose down -v:会删掉命名卷,数据库数据全没。
  • 把数据库端口映射到公网服务器的 0.0.0.0:数据库直接暴露在公网。不映射,或者只绑定 127.0.0.1:5432:5432。
  • 在 compose 文件里写真实密码并提交:用 .env(加入 .gitignore)或部署平台的密钥管理。
  • 镜像版本升级时数据目录变化:例如 PostgreSQL 新大版本的数据目录约定可能变化,升级前看官方镜像说明并备份。

面试常问

见 Docker 面试题:容器之间怎么通信、数据怎么持久化、depends_on 的局限。