如何解决Docker-Compose中Python应用依赖双健康检查失败问题?
问题原因及修复方案
核心问题
PostgREST容器的健康检查命令用了pg_isready,但这个工具属于PostgreSQL客户端组件,PostgREST官方镜像默认没有预装,导致健康检查持续失败,进而触发依赖它的app容器启动报错。
具体修复步骤
1. 修正PostgREST的健康检查逻辑
替换原有的pg_isready命令,改为直接检查PostgREST服务是否就绪。可以用wget或curl访问服务端点(PostgREST启动成功后会响应根路径请求):
postgrest: # ... 其他配置不变 healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1"] interval: 15s # 延长检查间隔,给服务足够时间连接数据库 timeout: 5s retries: 10 # 增加重试次数
如果容器内没有wget,也可以用curl版本:
test: ["CMD-SHELL", "curl -f http://localhost:3000/ > /dev/null 2>&1 || exit 1"]
2. 移除PostgREST不必要的Volume挂载
PostgREST是无状态服务,不需要挂载PostgreSQL的数据目录,删掉以下配置:
volumes: - ./data:/var/lib/postgresql/data:cached
多余的挂载可能引发文件权限问题,干扰服务正常启动。
3. 确保PostGIS初始化完成并创建所需角色
PostgREST的连接依赖${PGRST_DB_ANON_ROLE}指定的数据库角色,需要确保PostGIS容器中已创建该角色:
- 可以在PostGIS服务中添加环境变量,初始化时创建角色:
postgis: # ... 其他配置不变 environment: POSTGRES_USER: ${PGRST_DB_ANON_ROLE} POSTGRES_PASSWORD: your_password_here # 可根据需求设置,生产环境不建议留空
- 或者添加初始化脚本:在项目根目录创建
init-scripts文件夹,放入创建角色的SQL文件(如create-role.sql),然后挂载到PostGIS容器的/docker-entrypoint-initdb.d目录:
postgis: # ... 其他配置不变 volumes: - ./data:/var/lib/postgresql/data:cached - ./init-scripts:/docker-entrypoint-initdb.d
create-role.sql内容示例:
CREATE ROLE ${PGRST_DB_ANON_ROLE} WITH LOGIN; GRANT USAGE ON SCHEMA ${PGRST_DB_SCHEMA} TO ${PGRST_DB_ANON_ROLE}; GRANT SELECT ON ALL TABLES IN SCHEMA ${PGRST_DB_SCHEMA} TO ${PGRST_DB_ANON_ROLE};
修复后的完整docker-compose.yml示例
services: postgis: image: mdillon/postgis volumes: - ./data:/var/lib/postgresql/data:cached - ./init-scripts:/docker-entrypoint-initdb.d # 可选,用于初始化角色 ports: - 5432:5432 environment: POSTGRES_USER: ${PGRST_DB_ANON_ROLE} POSTGRES_PASSWORD: mydbpassword healthcheck: test: ["CMD-SHELL", "pg_isready -U ${PGRST_DB_ANON_ROLE} -d postgres"] interval: 10s timeout: 5s retries: 5 postgrest: image: postgrest/postgrest environment: PGRST_DB_URI: postgres://${PGRST_DB_ANON_ROLE}:mydbpassword@postgis:5432/postgres PGRST_DB_SCHEMA: ${PGRST_DB_SCHEMA} PGRST_DB_ANON_ROLE: ${PGRST_DB_ANON_ROLE} PGRST_DB_POOL: ${PGRST_DB_POOL} ports: - 3000:3000 healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1"] interval: 15s timeout: 5s retries: 10 app: image: newapp command: python main.py ports: - 5000:5000 depends_on: postgis: condition: service_healthy postgrest: condition: service_healthy
内容的提问来源于stack exchange,提问作者omkar
相关产品推荐
相关产品推荐

