PostgreSQL Docker容器SSL配置报错:服务器不支持SSL但要求使用SSL
问题排查与解决方案
一、解决SSL连接报错 server does not support SSL, but SSL was required
1. 验证证书权限与路径正确性
PostgreSQL运行用户(默认postgres)需要拥有证书文件的读取权限,且容器内路径必须与postgresql.conf中配置一致:
- 进入PostgreSQL容器执行:
ls -l /your/cert/path/ # 确保密钥文件(server.key)权限为600,证书/CA文件为644,所有者为postgres:postgres - 如果权限不符,可在宿主机调整后重新挂载,或在
docker-compose.yml中添加user: postgres,并确保宿主机证书目录权限对postgres用户开放。
2. 确认postgresql.conf是否生效
官方Docker PostgreSQL镜像的默认配置文件路径是/var/lib/postgresql/data/postgresql.conf,若你挂载到其他路径(如/etc/postgresql),需通过启动参数指定加载:
- 在
docker-compose.yml的PostgreSQL服务中添加命令:command: postgres -c config_file=/etc/postgresql/postgresql.conf - 验证SSL是否开启:进入容器执行
返回psql -U your_user -d your_db -c "show ssl;"on才说明配置生效。
3. 检查pg_hba.conf的SSL连接规则
需明确允许SSL连接的条目,否则即使SSL开启,客户端强制SSL时仍会报错:
- 在
pg_hba.conf中添加(根据你的网络调整IP段):hostssl all all 0.0.0.0/0 md5 - 同样确保
pg_hba.conf的挂载路径正确,或通过启动参数指定:-c hba_file=/etc/postgresql/pg_hba.conf
4. 修正FastAPI的数据库连接字符串
确保连接URL包含正确的SSL参数:
- 单向SSL(仅验证服务器证书):
DATABASE_URL = "postgresql+psycopg2://user:pass@db:5432/dbname?sslmode=require&sslrootcert=/path/to/rootCA.pem" - 双向SSL(客户端也需提供证书):
注意:客户端容器需正确挂载证书文件,路径与URL中一致。DATABASE_URL = "postgresql+psycopg2://user:pass@db:5432/dbname?sslmode=verify-full&sslrootcert=/path/to/rootCA.pem&sslcert=/path/to/client-cert.pem&sslkey=/path/to/client-key.pem"
二、解决PGDATA挂载时的initdb错误
官方PostgreSQL镜像初始化时,若PGDATA目录非空(如提前放入配置文件),会触发"目录非空"错误,正确做法:
1. 分离配置文件与PGDATA目录
不要将postgresql.conf/pg_hba.conf直接挂载到PGDATA,而是挂载到独立目录(如/etc/postgresql),然后通过启动参数指定加载,参考前文的command配置。
2. 初始化后再挂载配置
- 先启动PostgreSQL容器(不挂载自定义配置),完成数据库初始化:
docker-compose up -d db - 待容器运行后,将自定义配置文件复制到容器内的
PGDATA目录:docker cp ./postgresql.conf your-db-container:/var/lib/postgresql/data/ docker cp ./pg_hba.conf your-db-container:/var/lib/postgresql/data/ - 重启容器使配置生效。
3. 避免挂载非空目录到PGDATA
若必须挂载宿主机目录到PGDATA,确保该目录为空,或仅包含之前备份的数据库文件,不要放入配置文件等无关内容。
内容的提问来源于stack exchange,提问作者ETisREAL
相关产品推荐
相关产品推荐

