使用Docker部署PostgreSQL时如何解决‘角色"john"不存在’问题?
问题
使用Docker Compose部署PostgreSQL时出现认证失败,报错提示角色“john”不存在,具体错误日志:
2023-12-30 13:29:28 2023-12-30 16:29:28.298 UTC [35] FATAL: password authentication failed for user "john" 2023-12-30 13:29:28 2023-12-30 16:29:28.298 UTC [35] DETAIL: Role "john" does not exist. 2023-12-30 13:29:28 Connection matched file "/data/postgres/pg_hba.conf" line 140: "host all all all scram-sha-256"
启动命令:docker compose up -d
docker-compose.yml配置:
version: '3.7' services: postgres-inventory: container_name: postgres-inventory image: postgres environment: POSTGRES_DB: inventory-service POSTGRES_USER: john POSTGRES_PASSWORD: secret PGDATA: /data/postgres volumes: - ./postgres-inventory:/data/postgres ports: - "5432:5432" restart: unless-stopped
已尝试的解决措施:
- 检查环境变量:确认Docker Compose文件中
POSTGRES_USER和POSTGRES_PASSWORD配置无误; - 处理卷持久化:尝试删除并重建持久卷,避免旧数据残留;
- 检查访问控制配置:查看
pg_hba.conf文件,添加过如下规则:
也尝试添加过容器IP;host all all 127.0.0.1/32 trust - 执行
netstat -ano | findstr :5432杀死端口进程并重启主机,问题仍未解决。
相关文件内容:
data.sql:CREATE DATABASE IF NOT EXISTS 'inventory-service';application-docker.properties:spring.datasource.username=john spring.datasource.password=secret
疑问:是否遗漏了PostgreSQL初始化中创建角色的必要步骤?
解决方案
核心原因
Postgres官方镜像的POSTGRES_USER环境变量仅在首次初始化数据库(挂载卷为空)时生效,若卷中残留旧Postgres数据,镜像会跳过初始化流程,不会创建新角色。你之前的卷清理操作可能未彻底完成,导致旧数据残留,角色“john”未被创建。
具体修复步骤
- 彻底清理持久化数据
- 停止并删除容器及关联卷:
docker compose down -v - 手动删除本地挂载目录:
- Linux/macOS:
rm -rf ./postgres-inventory - Windows:
rmdir /s ./postgres-inventory
- Linux/macOS:
- 停止并删除容器及关联卷:
- 修正
data.sql语法错误
Postgres不支持带单引号的CREATE DATABASE IF NOT EXISTS语法,正确写法为:
实际上CREATE DATABASE IF NOT EXISTS inventory-service;POSTGRES_DB环境变量已自动创建该数据库,此文件可直接删除以避免冲突。 - 重新启动容器
执行docker compose up -d,此时卷为空,Postgres会执行初始化,自动创建角色john和数据库inventory-service。 - 验证角色状态
进入容器:docker exec -it postgres-inventory psql -U john -d inventory-service
执行\du命令查看角色列表,确认john存在且拥有对应数据库权限。
额外注意事项
- 不要手动修改容器内的
pg_hba.conf,容器重启后会被覆盖。如需自定义认证规则,可通过Docker挂载自定义pg_hba.conf到容器/var/lib/postgresql/data/pg_hba.conf路径,或在初始化脚本中添加修改命令。 - 确保本地5432端口未被其他Postgres实例占用,避免端口映射冲突。
内容的提问来源于stack exchange,提问作者Corvo
相关产品推荐
相关产品推荐

