Docker同网络中Tryton无法连接PostgreSQL:主机名解析失败
核心问题分析
你遇到的could not translate host name "postgres" to address错误,本质是Docker容器间的DNS解析失败——Tryton容器无法通过服务名postgres找到对应的PostgreSQL容器,和PostgreSQL本身是否就绪无关。
分步解决方案
1. 确认docker-compose.yml的服务名称匹配
Tryton配置中使用的postgres主机名,必须和docker-compose.yml里PostgreSQL服务的名称完全一致:
services: # 这里的服务名必须是postgres,和trytond.conf里的db_host对应 postgres: image: postgres:14-alpine environment: POSTGRES_USER: gnuhealth POSTGRES_PASSWORD: gnuhealth POSTGRES_DB: gnuhealth volumes: - postgres_data:/var/lib/postgresql/data tryton: build: . depends_on: - postgres ports: - "8000:8000"
如果PostgreSQL服务名不是postgres,请同步修改trytond.conf里的db_host参数。
2. 确保两个容器在同一Docker网络
Docker Compose默认会给项目创建专属网络,所有服务自动加入;如果手动配置了网络,必须让两个服务归属同一网络:
networks: gnuhealth_net: driver: bridge services: postgres: # ...其他配置 networks: - gnuhealth_net tryton: # ...其他配置 networks: - gnuhealth_net
避免一个用host网络、一个用默认桥接的混合配置,这会直接导致解析失败。
3. 修正trytond.conf的数据库配置
确保trytond.conf里的数据库连接参数正确指向PostgreSQL服务:
[database] db_type = postgresql db_host = postgres db_port = 5432 db_user = gnuhealth db_password = gnuhealth db_name = gnuhealth
不要用localhost或主机IP,必须用Docker服务名作为主机名。
4. 验证容器间网络连通性
进入Tryton容器,测试能否ping通PostgreSQL服务:
docker exec -it <你的tryton容器名称> ping postgres
如果ping不通,先清理旧容器和网络后重新构建:
docker-compose down -v docker-compose up --build
如果ping通但仍无法连接,再检查PostgreSQL的用户名、密码、数据库是否正确创建。
5. 补充:解决服务启动时机问题(可选)
虽然当前错误是解析问题,但depends_on只保证容器启动顺序,不保证PostgreSQL服务就绪。可以给Tryton添加启动等待脚本,避免提前连接:
在Tryton的Dockerfile中添加:
COPY wait-for-it.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/wait-for-it.sh CMD ["wait-for-it.sh", "postgres:5432", "--", "trytond", "-c", "/etc/trytond.conf"]
(wait-for-it.sh是一个轻量的等待脚本,用于检测端口是否就绪)
内容的提问来源于stack exchange,提问作者Matthias

