使用Docker Compose+Postgres时Docker Secrets用户识别失败
问题描述
执行以下命令:
docker exec -it db psql --user $(< postgres_user.txt)
出现报错:
/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "my_postgres_user" does not exist
配置与环境细节
compose.yaml 内容:
services: db: container_name: db image: postgres:16 environment: POSTGRES_USER_FILE: /run/secrets/postgres_user POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password POSTGRES_DB_FILE: /run/secrets/postgres_db secrets: - postgres_user - postgres_password - postgres_db ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data secrets: postgres_user: file: postgres_user.txt postgres_password: file: postgres_password.txt postgres_db: file: postgres_db.txt volumes: pgdata: {}
秘密文件均与compose.yaml同目录,以postgres_user.txt为例,内容无多余空格或换行:
my_postgres_user
已尝试操作
- 参考Docker Secrets及Postgres官方文档的Secrets示例,未找到适配
exec命令场景的方案 - 调整秘密文件存放位置(同目录/
/secrets目录),结果一致 - 通过Docker Desktop查看容器配置,发现Config中User字段为空;确认秘密文件已挂载,容器能读取到用户名,但误以为用户角色未创建
解决方法
1. 明确报错本质
报错提示的是数据库不存在,而非用户不存在:当psql仅指定--user参数时,会默认尝试连接与用户名同名的数据库,但你的配置通过POSTGRES_DB_FILE指定了自定义数据库名,因此默认连接的目标不存在。
2. 修正exec命令
执行命令时显式指定要连接的数据库名,同时直接读取容器内的secret文件(避免依赖本地文件):
docker exec -it db psql --user "$(cat /run/secrets/postgres_user)" --dbname "$(cat /run/secrets/postgres_db)"
3. 验证用户是否正常创建
若仍怀疑用户未生成,可进入容器执行以下命令验证:
docker exec -it db bash # 容器内执行 psql -U postgres -c "SELECT usename FROM pg_user;"
如果查询结果中包含my_postgres_user,说明用户已正常创建,问题仅出在psql命令未指定数据库。
4. 关键补充说明
- Postgres容器启动时,会通过
POSTGRES_USER_FILE创建对应的用户角色,同时通过POSTGRES_DB_FILE创建指定数据库,并将该数据库的所有权赋予POSTGRES_USER_FILE中的用户 - 容器Config中的User字段为空是正常现象,Postgres容器默认以内置的
postgres用户运行,而非你创建的业务用户 - 本地执行
$(< postgres_user.txt)是读取本地文件内容,容器内的secret文件路径为/run/secrets/xxx,直接读取容器内的secret更可靠
内容的提问来源于stack exchange,提问作者eggroll
相关产品推荐
相关产品推荐

