Github Actions中Actix Web项目Cargo Test连接PostgreSQL失败
解决Actix Web CI工作流中Cargo Test无法连接Postgres的问题
问题现象
- CI工作流里「Test postgres connection」步骤用
psql能成功连接Postgres,但「Cargo test」步骤抛出连接拒绝错误 - 本地运行
cargo test完全正常
问题根源
在GitHub Actions的容器化环境中:
- 你的Job使用
rust:latest容器作为运行环境 services配置的Postgres是独立容器,和rust容器处于同一虚拟网络- 容器间需要通过服务名(此处为
postgres)互相访问,而非localhost(localhost指向rust容器自身,而非Postgres容器) - psql步骤能成功是因为显式指定了
-h postgres,但测试代码硬写了localhost,导致连接目标错误
解决方案
方案1:通过环境变量适配本地与CI环境(推荐)
- 修改测试代码,新增读取
POSTGRES_HOST环境变量的逻辑,本地默认用localhost,CI用服务名:
impl Context { fn new() -> Self { dotenv().ok(); let psql_user = env::var("POSTGRES_USER").expect("POSTGRES_USER must be set for integration tests"); let psql_pw = env::var("POSTGRES_PASSWORD") .expect("POSTGRES_PASSWORD must be set for integration tests"); // 读取POSTGRES_HOST,默认localhost适配本地环境 let psql_host = env::var("POSTGRES_HOST").unwrap_or_else(|_| "localhost".to_string()); let database_url = format!( "postgres://{}:{}@{}:5432/postgres", psql_user, psql_pw, psql_host ); let mut conn = PgConnection::establish(&database_url) .expect("Failed to connect to the database 'postgres'"); // ... } }
- 在CI工作流的「Cargo test」步骤中添加
POSTGRES_HOST环境变量:
- name: Cargo test uses: actions-rs/cargo@v1 with: command: test args: --verbose env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_HOST: postgres
方案2:直接修改代码中的主机名(仅适配CI,不推荐)
如果只需要CI环境运行,可直接把代码里的localhost改成postgres,但本地测试需要额外调整Postgres访问配置:
let database_url = format!( "postgres://{}:{}@postgres:5432/postgres", psql_user, psql_pw );
验证
修改后重新触发CI,测试代码会使用正确的主机名连接Postgres容器,即可解决连接拒绝问题。
内容的提问来源于stack exchange,提问作者user15310712
相关产品推荐
相关产品推荐

