Docker容器连接故障:Web应用、PostgreSQL与golang-migrate连接异常排查
问题排查与解决方案
针对你遇到的两个连接错误,分别从Web应用、migrate工具及Docker配置层面逐一排查:
一、Web应用Unix套接字连接错误
核心问题
你的连接字符串使用了Unix套接字模式(host=/tmp),但Docker容器中PostgreSQL默认将套接字放在/var/run/postgresql/.s.PGSQL.5432,且跨容器场景下未共享该目录时,Web应用容器无法访问PostgreSQL的套接文件。
修复方案
1. 切换为TCP连接(推荐)
跨容器通信优先用TCP,利用Docker服务名做DNS解析。修改Go代码中的连接字符串格式:
// 从环境变量读取或直接定义(需与docker-compose配置匹配) dbURL := "postgres://root:your_password@postgres:5432/your_db_name?sslmode=disable" db, err := sql.Open("postgres", dbURL)
其中postgres是docker-compose中PostgreSQL服务的名称,容器间可直接通过服务名访问。
2. (可选)共享套接字目录
若坚持用Unix套接字,需在docker-compose中给两个容器挂载共享卷:
services: web: # 其他配置 volumes: - pg_socket:/var/run/postgresql/ environment: DATABASE_URL: "postgres://root@/your_db_name?host=/var/run/postgresql&sslmode=disable" postgres: # 其他配置 volumes: - pg_socket:/var/run/postgresql/ volumes: pg_socket:
二、migrate工具DNS解析错误
核心问题
lookup postgres on 127.0.0.11:53: server misbehaving 通常是以下原因:
- migrate服务与PostgreSQL不在同一Docker网络
- PostgreSQL未完全就绪时migrate已启动
- 服务名拼写错误或网络配置异常
修复方案
1. 确保网络与依赖配置
在docker-compose中给migrate服务添加健康检查依赖,确保PostgreSQL完全启动后再执行迁移:
services: postgres: image: postgres:15-alpine environment: POSTGRES_USER: root POSTGRES_PASSWORD: your_password POSTGRES_DB: your_db_name healthcheck: test: ["CMD-SHELL", "pg_isready -U root -d your_db_name"] interval: 3s timeout: 3s retries: 5 migrate: image: migrate/migrate volumes: - ./migrations:/migrations command: ["-path", "/migrations", "-database", "postgres://root:your_password@postgres:5432/your_db_name?sslmode=disable", "up"] depends_on: postgres: condition: service_healthy
2. 验证网络一致性
默认情况下docker-compose会创建统一的bridge网络,若自定义了网络,需确保migrate和PostgreSQL都加入该网络:
networks: app_network: driver: bridge services: web: networks: [app_network] postgres: networks: [app_network] migrate: networks: [app_network]
3. 强制刷新Docker DNS
若仍存在解析问题,重启Docker服务可修复内置DNS异常:
sudo systemctl restart docker # Linux # 或在Windows/macOS上通过Docker Desktop重启
三、通用检查项
- 确认docker-compose中PostgreSQL的
POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB与Web应用、migrate的连接字符串完全匹配 - 避免在连接字符串中遗漏
sslmode=disable(容器内PostgreSQL默认未开启SSL) - 执行
docker-compose logs postgres查看PostgreSQL启动日志,确认服务正常运行
内容的提问来源于stack exchange,提问作者NerdySteve
相关产品推荐
相关产品推荐

