文章
Docker应用间网络连接指南
目录
- 在 Docker 中,应用容器连接数据库或其他容器,关键点是 网络必须正确,Host 用容器名/服务名或宿主机地址,大致有以下5种情况。
- 1️⃣ 容器与容器在同一自定义网络(推荐)
- ✅ DATABASE_URL 中 host=pg(容器名)
- 2️⃣ 单独 docker 容器访问 docker-compose 容器
- ✅ Host=db(docker-compose 服务名)
- 3️⃣ docker-compose 容器访问单独 docker 容器
- ✅ Host=mydb(docker run 容器名)
- 4️⃣ 容器访问宿主机数据库或宿主机端口映射
- ⚠️ Linux 需加 --add-host=host.docker.internal:host-gateway
- 5️⃣ 宿主机直接访问数据库
- 6️⃣ 测试与故障排查
- 🔑 总结快速决策
在 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_URL 中 host=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️⃣ 宿主机直接访问数据库#
- 场景:非容器应用或客户端在本机访问数据库
- 方法:使用
localhost或127.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-compose | compose 容器名/服务名 | 同一网络 |
| docker-compose → docker run | docker run 容器名 | 同一网络 |
| 容器访问宿主机端口 | host.docker.internal | 端口已映射 |
| 宿主机访问 | localhost / 127.0.0.1 | 端口已映射 |
- 推荐开发方式:数据库 + 应用容器放同一网络,用容器名访问
- 端口映射方式:容器访问宿主机用
host.docker.internal - 连接字符串格式:
postgresql+asyncpg://user:pass@host:port/dbname