Docker化Django应用连接PostgreSQL失败:无法解析主机名'db'
问题解决:Docker化Django项目Datadog上报与数据库解析冲突
核心矛盾分析
添加network_mode: host后,容器共享宿主机网络栈,导致Docker Compose内部的服务名db无法通过容器DNS解析;而移除该配置后,Datadog追踪数据又无法正常上报。以下是两种针对性解决方案:
方案1:放弃host网络,修复Datadog上报(推荐)
遵循容器化最佳实践,通过自定义网络实现容器间通信,同时确保Datadog Agent能接收追踪数据:
配置Docker Compose自定义网络
在docker-compose.yml中定义专属网络,让app、db、datadog-agent容器处于同一网络:networks: app-network: driver: bridge services: app: build: . command: python manage.py runserver 0.0.0.0:8000 environment: - DD_AGENT_HOST=datadog-agent # 用Agent服务名替代localhost - DD_TRACE_ENABLED=true - DD_TRACE_AGENT_PORT=8126 - DATABASE_URL=postgres://user:password@db:5432/db_name # 保留db服务名 networks: - app-network depends_on: - db - datadog-agent db: image: postgres:15 environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=password - POSTGRES_DB=db_name networks: - app-network datadog-agent: image: gcr.io/datadoghq/agent:latest networks: - app-network environment: - DD_API_KEY=你的Datadog密钥 - DD_APM_ENABLED=true - DD_APM_NON_LOCAL_TRAFFIC=true # 允许跨容器发送追踪数据 volumes: - /var/run/docker.sock:/var/run/docker.sock - /proc/:/host/proc/:ro - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro验证连通性
进入app容器执行curl datadog-agent:8126,若返回OK则说明Agent连通正常,此时Django的追踪数据可正常上报。
方案2:保留host网络,修复数据库解析
若因特殊需求必须使用network_mode: host,需调整数据库的访问方式:
修改PostgreSQL配置
- 在PostgreSQL容器的
postgresql.conf中设置listen_addresses = '*',允许外部访问 - 在
pg_hba.conf中添加规则:host all all 0.0.0.0/0 md5(生产环境建议限制具体IP段,避免安全风险)
- 在PostgreSQL容器的
映射数据库端口到宿主机
在docker-compose.yml的db服务中添加端口映射:services: db: image: postgres:15 ports: - "5432:5432" # 映射宿主机5432端口 environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=password - POSTGRES_DB=db_name更新Django数据库连接地址
将数据库URL中的db替换为localhost:DATABASE_URL=postgres://user:password@localhost:5432/db_name此时app容器通过宿主机的localhost访问映射的PostgreSQL端口,可正常解析连接。
关键注意事项
- 优先选择方案1,
network_mode: host会破坏容器网络隔离,容易引发端口冲突、权限泄露等问题 - 若使用方案2,务必严格限制PostgreSQL的访问IP范围,避免暴露安全隐患
- 测试时可先单独验证Datadog Agent的连通性,再测试数据库连接,逐步排查问题
内容的提问来源于stack exchange,提问作者Huzaifa Arshad
相关产品推荐
相关产品推荐

