Docker Compose部署docker-osm时PostgreSQL用户认证匹配失败排查
问题背景
使用kartoza的docker-osm项目提供的docker-compose部署时遇到PostgreSQL认证问题,docker-compose配置如下:
version: '3.4' volumes: osm-postgis-data: settings-data: import_done: import_queue: cache: services: db: image: kartoza/postgis:${POSTGRES_VERSION} environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASS=${POSTGRES_PASS} - POSTGRES_DBNAME=${POSTGRES_DBNAME} - ALLOW_IP_RANGE=${ALLOW_IP_RANGE} - FORCE_SSL=${FORCE_SSL} volumes: - osm-postgis-data:/var/lib/postgresql - settings-data:/home/settings healthcheck: test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DBNAME} -U ${POSTGRES_USER}"] imposm: image: kartoza/docker-osm:imposm-latest volumes: - settings-data:/home/settings - import_done:/home/import_done - import_queue:/home/import_queue - cache:/home/cache depends_on: db: condition: service_healthy environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASS=${POSTGRES_PASS} - POSTGRES_DBNAME=${POSTGRES_DBNAME} - POSTGRES_PORT=${POSTGRES_PORT} - POSTGRES_HOST=${POSTGRES_HOST} - TIME=${TIME} - SETTINGS=${SETTINGS} - CACHE=${CACHE} - IMPORT_DONE=${IMPORT_DONE} - IMPORT_QUEUE=${IMPORT_QUEUE} - SRID=${SRID} - OPTIMIZE=${OPTIMIZE} - DBSCHEMA_PRODUCTION=${DBSCHEMA_PRODUCTION} - DBSCHEMA_IMPORT=${DBSCHEMA_IMPORT} - DBSCHEMA_BACKUP=${DBSCHEMA_BACKUP} - QGIS_STYLE=${QGIS_STYLE} - CLIP=${CLIP} - SSL_MODE=${SSL_MODE} osmupdate: image: kartoza/docker-osm:osmupdate-latest volumes: - settings-data:/home/settings - import_done:/home/import_done - import_queue:/home/import_queue - cache:/home/cache depends_on: db: condition: service_healthy environment: - MAX_DAYS=${MAX_DAYS} - DIFF=${DIFF} - MAX_MERGE=${MAX_MERGE} - COMPRESSION_LEVEL=${COMPRESSION_LEVEL} - BASE_URL=${BASE_URL} - IMPORT_QUEUE=${IMPORT_QUEUE} - IMPORT_DONE=${IMPORT_DONE} - TIME=${TIME} osmenrich: image: kartoza/docker-osm:osmenrich-latest volumes: - settings-data:/home/settings - import_done:/home/import_done - import_queue:/home/import_queue - cache:/home/cache depends_on: db: condition: service_healthy environment: - IMPORT_QUEUE=${IMPORT_QUEUE} - IMPORT_DONE=${IMPORT_DONE} - TIME=${TIME} - DBSCHEMA_PRODUCTION=${DBSCHEMA_PRODUCTION} - SSL_MODE=${SSL_MODE}
报错信息
执行docker-compose up时首次报错:
root@gis FATAL: role "root" does not exist
修改db服务的healthcheck配置后,又出现:
dockerosm-db-1 | 2023-09-26 08:46:34.632 UTC \[236\] docker@gis LOG: provided user name (docker) and authenticated user name (root) do not match dockerosm-db-1 | 2023-09-26 08:46:34.632 UTC \[236\] docker@gis FATAL: Peer authentication failed for user "docker" dockerosm-db-1 | 2023-09-26 08:46:34.632 UTC \[236\] docker@gis DETAIL: Connection matched pg_hba.conf line 94: "local all all peer"
排查方向与解决建议
1. 环境变量加载验证
- 确认
.env文件存在于docker-compose同目录,且POSTGRES_USER、POSTGRES_DBNAME等变量无拼写错误。 - 执行
docker-compose config查看渲染后的配置,检查healthcheck中的${POSTGRES_USER}是否被替换为预期用户名。若仍显示变量名,说明环境变量未加载,需确保.env路径正确,或运行时添加--env-file参数指定文件。
2. Healthcheck执行身份问题
Docker容器的healthcheck默认以root用户执行,而PostgreSQL的peer认证会将操作系统用户名(此处为root)作为数据库登录用户名,直接忽略-U参数,这是导致认证不匹配的核心原因。解决方式二选一:
- 切换为PostgreSQL系统用户执行检查:
healthcheck: test: ["CMD-SHELL", "su - postgres -c 'pg_isready -d ${POSTGRES_DBNAME} -U ${POSTGRES_USER}'"] - 改用TCP连接绕过本地socket的peer认证:
healthcheck: test: ["CMD-SHELL", "pg_isready -d ${POSTGRES_DBNAME} -U ${POSTGRES_USER} -h localhost"]
3. PostgreSQL用户初始化验证
若为首次启动容器,进入db容器执行psql -U postgres,再用\du命令查看用户列表,确认POSTGRES_USER指定的用户是否存在。若用户不存在,需删除osm-postgis-data卷后重新启动(注意备份数据):
docker volume rm osm-postgis-data docker-compose up
4. pg_hba.conf规则调整
从错误日志看,本地连接匹配了peer认证规则。若需保留本地socket连接并使用密码认证,可修改容器内pg_hba.conf,将local all all peer改为local all all md5。但更推荐通过修改healthcheck连接方式解决,避免直接改动容器内PostgreSQL配置。
内容的提问来源于stack exchange,提问作者papa_celik
相关产品推荐
相关产品推荐

