返回文章列表

文章

Docker应用间网络连接指南

目录
  1. 在 Docker 中,应用容器连接数据库或其他容器,关键点是 网络必须正确,Host 用容器名/服务名或宿主机地址,大致有以下5种情况。
  2. 1️⃣ 容器与容器在同一自定义网络(推荐)
  3. ✅ DATABASE_URL 中 host=pg(容器名)
  4. 2️⃣ 单独 docker 容器访问 docker-compose 容器
  5. ✅ Host=db(docker-compose 服务名)
  6. 3️⃣ docker-compose 容器访问单独 docker 容器
  7. ✅ Host=mydb(docker run 容器名)
  8. 4️⃣ 容器访问宿主机数据库或宿主机端口映射
  9. ⚠️ Linux 需加 --add-host=host.docker.internal:host-gateway
  10. 5️⃣ 宿主机直接访问数据库
  11. 6️⃣ 测试与故障排查
  12. 🔑 总结快速决策

在 Docker 中,应用容器连接数据库或其他容器,关键点是 网络必须正确,Host 用容器名/服务名或宿主机地址,大致有以下5种情况#

1️⃣ 容器与容器在同一自定义网络(推荐)#

  • 场景:应用容器和数据库容器都在 Docker 内,并加入同一自定义网络
  • 原理:同一网络内,容器名可被 DNS 解析 示例(PowerShell):
# 创建自定义网络
docker network create news-net

# 启动数据库容器
docker run -d --name pg --network news-net `
    -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=newsletter `
    postgres:15

# 启动应用容器
docker run -d --name app --network news-net `
    -e DATABASE_URL="postgresql+asyncpg://postgres:123456@pg:5432/newsletter" `
    myapp

DATABASE_URLhost=pg(容器名)#

2️⃣ 单独 docker 容器访问 docker-compose 容器#

  • 场景:docker run 启动的应用访问 docker-compose 启动的数据库
  • 要求:两个容器在同一网络 方法:
# 假设 docker-compose 网络名 news-net
docker run -d --name myapp --network news-net `
    -e DATABASE_URL="postgresql+asyncpg://postgres:123456@db:5432/newsletter" `
    myapp-image

docker-compose.yml 中数据库服务:

services:
  db:
    image: postgres:15
    container_name: db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 123456
      POSTGRES_DB: newsletter
    networks:
      - news-net

networks:
  news-net:
    external: true

Host=db(docker-compose 服务名)#

3️⃣ docker-compose 容器访问单独 docker 容器#

  • 场景:docker-compose 启动的应用访问 docker run 启动的数据库
  • 要求:两个容器在同一网络 方法:
# docker run 容器加入 compose 网络
docker run -d --name mydb --network news-net `
    -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=newsletter `
    postgres:15

docker-compose.yml 中应用服务:

services:
  app:
    build: .
    environment:
      DATABASE_URL: postgresql+asyncpg://postgres:123456@mydb:5432/newsletter
    networks:
      - news-net

networks:
  news-net:
    external: true

Host=mydb(docker run 容器名)#

4️⃣ 容器访问宿主机数据库或宿主机端口映射#

  • 场景:应用容器访问宿主机上运行的数据库或映射端口
  • 方法:使用 host.docker.internal(Windows/macOS) 示例:
# 宿主机端口映射 5432
docker run -d --name app `
    -e DATABASE_URL="postgresql+asyncpg://postgres:123456@host.docker.internal:5432/newsletter" `
    myapp

⚠️ Linux 需加 --add-host=host.docker.internal:host-gateway#

5️⃣ 宿主机直接访问数据库#

  • 场景:非容器应用或客户端在本机访问数据库
  • 方法:使用 localhost127.0.0.1 示例(PowerShell):
$env:DATABASE_URL="postgresql+asyncpg://postgres:123456@localhost:5432/newsletter"

6️⃣ 测试与故障排查#

# 测试容器内连通性
docker run -it --rm --network news-net postgres:15 psql -h pg -U postgres -d newsletter

# 或进入应用容器
docker exec -it app bash
echo $DATABASE_URL

常见问题:

  • could not connect 或超时 → 数据库未就绪
  • 解决办法:
    • 应用启动重试
    • docker-compose healthcheck + depends_on

🔑 总结快速决策#

场景Host 填写方式网络要求
容器互连容器名/服务名同一自定义网络
docker run → docker-composecompose 容器名/服务名同一网络
docker-compose → docker rundocker run 容器名同一网络
容器访问宿主机端口host.docker.internal端口已映射
宿主机访问localhost / 127.0.0.1端口已映射
  • 推荐开发方式:数据库 + 应用容器放同一网络,用容器名访问
  • 端口映射方式:容器访问宿主机用 host.docker.internal
  • 连接字符串格式postgresql+asyncpg://user:pass@host:port/dbname