我曾以为在 zeabur dashboard 更新环境变量并重启服务就会自动更新 database password,我天真了。😅
希望朋友们能以我为戒,能跳过这个坑。

在接到 Zeabur 安全事件更新的邮件时,我的第一反应很自然:打开 Zeabur,改数环境变量,重启项目。
面板上的 POSTGRES_PASSWORD 已经是新值了,服务也重新跑起来了。按常见 PaaS 的直觉,这应该已经轮换完成。
然后两件怪事同时出现:
- 应用改用新密码后,日志变成
password authentication failed for user。 - 旧密码还能连上数据库;
问题不是重启没执行,而是重启没有帮我更新 database password。
环境变量只在空 volume 第一次初始化时生效
Zeabur 的 PostgreSQL 服务会把数据放在持久化 volume 里,路径通常是 /var/lib/postgresql/data。
Postgres Docker 官方镜像写得很清楚:POSTGRES_PASSWORD 这类变量,只在数据目录还是空的时候用来创建超级用户。目录里一旦有了数据库,之后再改环境变量、再重启容器,都不会去改已经存在的角色密码。
Zeabur 重启只是把容器拉起来。volume 还在,Postgres 继续用第一次初始化时写入的密码。
所以会出现分叉:
- Zeabur 面板显示新密码;
- Postgres server 仍接受旧密码;
- 应用如果去信面板,就会连错。
正确的轮换顺序
- 生成一段 URL 安全的新密码,避免
@ : / % # +,免得写进DATABASE_URL还要编码:
openssl rand -hex 32- 打开 PostgreSQL 服务的终端,进入数据库:
psql -U root -d vmemo_prod- 在 Postgres 里改角色密码:
ALTER USER root WITH PASSWORD '新密码';ALTER USER 一生效,旧密码立刻不能从其他服务连进来。
- 马上把应用的
DATABASE_URL改成带新密码的字面量,不要再留${...}模板。 - 重启的是**应用服务**,不是指望重启 Postgres 来改密码。
- 最后把 Zeabur 面板里的
PASSWORD、POSTGRES_PASSWORD改成同一个新值。这一步只是让面板和真实密码重新对齐,它不会反向写入 Postgres。
两个容易误判的点
在 Postgres 容器内部跑 psql,本地 socket 常常是 trust,不校验密码。这会让人误以为“新密码已经生效了”。应用在另一个服务里走 TCP,用的是角色的真实密码。
改密码之后,不要只改 Zeabur 变量。应用连接串不一起改,服务会立刻打不开。