⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

10.3.2 服务之间如何对话——网络与卷:服务间通信与数据共享

容器间通信,用服务名就行。

Docker Compose 网络原理

Docker Compose 会自动为项目创建一个专属网络,所有服务都加入这个网络。在这个网络中,服务可以通过服务名相互访问。

服务间通信

使用服务名作为主机名

yaml
services:
  api:
    environment:
      # 使用服务名 postgres 而非 localhost
      - DATABASE_URL=postgresql://user:pass@postgres:5432/mydb
      # 使用服务名 redis
      - REDIS_URL=redis://redis:6379

常见错误

在容器内使用 localhost 是访问容器自己,而非其他服务。必须使用服务名!

端口规则

场景配置说明
容器间通信直接使用容器端口postgres:5432
外部访问需要端口映射ports: "5432:5432"
仅内部访问使用 exposeexpose: ["5432"]
yaml
services:
  postgres:
    image: postgres:15
    # 不映射端口,外部无法直接访问,更安全
    expose:
      - "5432"

自定义网络

多网络隔离

yaml
services:
  frontend:
    networks:
      - frontend-network
  
  api:
    networks:
      - frontend-network
      - backend-network
  
  postgres:
    networks:
      - backend-network  # 数据库不暴露给前端

networks:
  frontend-network:
  backend-network:

网络别名

yaml
services:
  postgres:
    networks:
      default:
        aliases:
          - db
          - database

现在可以用 postgresdbdatabase 三个名称访问同一服务。

数据卷详解

卷的类型

类型语法特点
命名卷volume-name:/pathDocker 管理,持久化
绑定挂载./host/path:/container/path直接映射主机目录
匿名卷/path临时,容器删除即丢失

命名卷(推荐用于数据持久化)

yaml
services:
  postgres:
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:  # 声明命名卷
    driver: local

绑定挂载(开发时常用)

yaml
services:
  api:
    volumes:
      # 将本地代码挂载到容器,实现热重载
      - ./api:/app
      # 排除 node_modules(使用匿名卷)
      - /app/node_modules

只读挂载

yaml
services:
  nginx:
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

数据共享场景

场景一:多服务共享数据

yaml
services:
  api:
    volumes:
      - shared-uploads:/app/uploads

  worker:
    volumes:
      - shared-uploads:/app/uploads

volumes:
  shared-uploads:

场景二:初始化脚本

yaml
services:
  postgres:
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro

PostgreSQL 会在首次启动时自动执行 /docker-entrypoint-initdb.d/ 下的脚本。

查看网络和卷

bash
# 查看项目网络
docker network ls | grep myproject

# 查看网络详情
docker network inspect myproject_default

# 查看卷
docker volume ls

# 查看卷详情
docker volume inspect myproject_postgres-data

清理资源

bash
# 停止并删除容器,但保留卷
docker compose down

# 停止并删除容器和卷(危险!数据会丢失)
docker compose down -v

# 删除未使用的卷
docker volume prune

数据安全

docker compose down -v 会删除所有数据卷,生产环境慎用!

最佳实践

  1. 生产环境不映射数据库端口:避免外部直接访问
  2. 使用命名卷持久化数据:比绑定挂载更可靠
  3. 敏感服务使用独立网络:隔离前后端
  4. 定期备份数据卷:使用 docker run 挂载卷并执行备份