写了 depends_on,为什么还是连不上 PostgreSQL?
depends_on 短写法只管启动顺序。先确认 db:5432,再用 TCP 健康检查等待就绪,账号和建表要另行验证。
Compose 写了 depends_on,应用启动却报 PostgreSQL Connection refused,重启应用后又好了。先查地址,再对照数据库启动时间。短写法只安排容器顺序,不会等待数据库接受 TCP 连接或完成建表。
先看应用究竟连到了哪里
普通 Compose 网络中,数据库服务名为 db,应用应使用 db:5432。应用容器内的 localhost 指它自己;宿主机发布的端口则用于宿主机或外部访问,不能混成一个地址。
docker compose ps -a
docker compose logs --tail=100 db
docker compose logs --tail=100 app
服务名按实际替换。将失败时间与数据库日志对应:正式监听前失败、稍后恢复,才符合就绪时序问题;一直拒绝连接还要看监听范围与网络。报错改成密码认证失败或表不存在时,转查账号或迁移,不继续增加等待秒数。
等待正式 TCP 服务,再启动应用
下面是依赖关系片段,保留原来的镜像版本、卷、环境配置和应用连接串,不要把它当作完整新项目:
services:
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 3s
retries: 12
start_period: 20s
app:
depends_on:
db:
condition: service_healthy
此例要求数据库镜像包含 pg_isready,并设置 POSTGRES_USER、POSTGRES_DB。$$ 将变量留给容器 shell 展开。检查显式使用 TCP,避免把只监听 socket 的初始化进程当成已对应用开放。
pg_isready 只说明服务器是否接受连接,不验证应用密码或业务表。独立迁移任务可以用成功退出的依赖条件表达,但要先确认任务失败会返回失败退出码。应用自身仍需有有限重试,处理数据库运行期间的短暂中断。
初始化脚本连 localhost 失败,是另一条分支
PostgreSQL 官方镜像在首次初始化时启动的临时进程只监听 Unix socket。/docker-entrypoint-initdb.d/ 内的脚本若继承 PGHOST=localhost,可能在正式 TCP 服务启动前失败。按该镜像约定,通过本地 socket 执行:
# 仅用于官方镜像的初始化脚本环境
unset PGHOST
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" \
--dbname "$POSTGRES_DB" -c 'SELECT 1;'
已有数据目录会跳过首次初始化。脚本曾经失败时,不要删除业务数据卷来强迫重跑;核对缺失对象,使用受控迁移补齐。
用应用账号,实际请求一次数据库
修改前备份数据库和原配置,在维护窗口检查启动顺序。应用应能用自己的账号连接,并完成一条依赖数据库的实际请求。没有必要为了这项修改切换 PostgreSQL 主版本。
如果启动问题修好后仍经常因内存不足退出,再按应用与数据库的内存预算判断增配。纯粹的地址或时序问题,在更贵的服务器上仍会出现。
应用与 PostgreSQL 共机时,可以从 2 核、4 GB 内存开始试部署,按数据库规模、镜像和恢复临时空间配盘。个人项目可比较 雨云 RCS 的应用配置;需要组合现有云资源时,可查看 ECS 的实例与地域。这个配置只是试部署的起点,数据库地址、TCP 就绪和初始化脚本仍分别检查,容量增加不会修复连接目标。




