You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中运行Rails遇PG::ConnectionBad错误:无法解析主机名pg

解决Docker Compose中Rails无法连接PostgreSQL服务的PG::ConnectionBad错误

这个问题我之前在搭建Rails+Docker环境时也踩过坑,核心原因是Docker内部DNS解析和Rails数据库配置不匹配,再加上PostgreSQL服务启动就绪的时序问题,一步步来解决:

1. 先检查Rails的数据库配置文件

首先确保你的config/database.yml里,development环境的host字段设置成了Docker Compose中PostgreSQL服务的名称pg——Docker Compose会自动为同一网络内的服务创建DNS解析,服务名就是默认的主机名。示例配置如下:

development:
  adapter: postgresql
  encoding: unicode
  database: your_app_name_development
  pool: 5
  username: postgres
  password: <%= ENV.fetch("POSTGRES_PASSWORD") { "" } %>
  host: pg
  port: 5432

注意这里的username默认是postgres(官方镜像的默认用户),如果你在Docker Compose里自定义了用户名,要对应上。

2. 完善PostgreSQL服务的Docker配置

官方postgres镜像默认需要设置必要的环境变量,否则可能出现认证或初始化问题。修改你的docker-compose.yml中pg服务的配置:

pg:
  image: postgres
  volumes:
    - ./tmp/db:/var/lib/postgresql/data
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: your_secure_password # 建议用.env文件管理敏感信息
    POSTGRES_DB: your_app_name_development # 可选,提前创建数据库,避免Rails初始化时出错

添加这些环境变量后,PostgreSQL启动时会自动创建指定的数据库和用户,和Rails的配置完全对应。

3. 处理服务启动的时序问题

depends_on只是保证pg服务先启动,但不保证PostgreSQL已经完全就绪(比如还在初始化数据库文件),这时候Rails服务启动会直接连接失败。可以用wait-for-it脚本让web服务等待pg就绪后再启动:

第一步:在Dockerfile中安装wait-for-it

RUN apt-get update && apt-get install -y wait-for-it

第二步:修改web服务的command

web:
  build: .
  command: >
    sh -c "wait-for-it pg:5432 -- bundle exec rails server -p 3000 -b '0.0.0.0'"
  volumes:
    - .:/app
  ports:
    - "3000:3000"
  depends_on:
    - pg
  # links字段可以去掉,Docker Compose默认同一网络下服务可互相访问

4. 验证网络连通性(排查用)

如果还是不行,可以进入web容器测试能不能解析pg主机:

docker-compose exec web ping pg

如果能ping通,说明网络没问题,再仔细检查Rails的database.yml配置;如果ping不通,查看Docker网络:

docker network ls
docker inspect <你的项目名_default>

确认pg和web服务都在同一个网络里。

内容的提问来源于stack exchange,提问作者Chloe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:33:25