GitHub Actions中PostgreSQL密码认证失败问题排查
问题分析与解决方案
你的核心问题出在容器网络访问逻辑和主机名配置上,具体原因和修复步骤如下:
错误原因
当你给job指定container: python:3.11-buster后,整个job的所有步骤都会在这个Python容器内执行。此时:
localhost指向的是Python容器本身,而非你定义的postgres服务容器- 你配置的
ports: -5432:5432是将postgres容器的端口映射到GitHub Runner的宿主机,而非Python容器内部,所以Python容器通过localhost:5432访问的是自身的端口(无postgres服务);如果本地runner宿主机恰好有postgres服务,就会连接到宿主机的postgres,但密码不匹配导致认证失败。
同时,GitHub Actions会自动为job容器和services容器创建共享网络,你可以直接通过服务名称(这里是postgres)访问postgres容器,无需端口映射。
修复步骤
1. 修改GitHub Actions配置文件
移除postgres服务的ports配置(不需要映射到宿主机),修改后的.yml文件如下:
name: Temporary Test Workflow jobs: temp_test: runs-on: ubuntu-latest container: image: python:3.11-buster services: postgres: image: postgres env: POSTGRES_DB: postgres POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v3 - name: connect_and_test run: | pip install pipenv pipenv install --deploy --system --dev python -m connection_test
2. 修改数据库连接的主机名
将connection_test.py中的数据库URL主机名从localhost改为postgres:
import asyncio import asyncpg async def main(): db_url = ( f"postgresql://postgres:postgres@postgres:5432/postgres" ) print(f"Starting connection on '{db_url}'") conn = await asyncpg.connect(db_url) print(await conn.execute("select 'OK'")) await conn.close() if __name__ == "__main__": asyncio.run(main())
验证逻辑
修改后,Python容器会通过共享网络直接访问postgres服务容器,使用你配置的用户名和密码即可正常认证;同时健康检查确保postgres服务完全启动后才执行测试步骤,避免连接时服务未就绪的问题。
内容的提问来源于stack exchange,提问作者MajorXaker
相关产品推荐
相关产品推荐

