Docker构建Rust API失败:数据库连接报错Cannot assign requested address
Rust API Docker构建时PostgreSQL连接失败(os error 99)排查
错误日志
#0 131.9 error: error communicating with database: Cannot assign requested address (os error 99) #0 131.9 --> src/persistance/answers_dao.rs:33:22 #0 131.9 | #0 131.9 33 | let record = sqlx::query!( #0 131.9 | ______________________^ #0 131.9 34 | | r#" #0 131.9 35 | | INSERT INTO answers ( question_uuid, content ) #0 131.9 36 | | VALUES ( $1, $2 ) #0 131.9 ... | #0 131.9 40 | | answer.content #0 131.9 41 | | ) #0 131.9 | |_________^ #0 131.9 | #0 131.9 = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info) #0 131.9 #0 131.9 error: error communicating with database: Cannot assign requested address (os error 99) #0 131.9 --> src/persistance/answers_dao.rs:75:23 #0 131.9 | #0 131.9 75 | let records = sqlx::query!("SELECT * FROM answers WHERE question_uuid = $1", question_uuid) #0 131.9 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #0 131.9 | #0 131.9 = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info) #0 131.9 #0 132.1 error: could not compile `rest_api` due to 2 previous errors
现有Docker Compose配置
version: "3.9" services: postgresdb: container_name: postgresdb image: "postgres:13.3" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=1234 - POSTGRES_DB=rustdb volumes: - rust_api_data:/var/lib/postgresql/data rust_backend: container_name: rust_backend image: rust-api:1.0.0 build: . ports: - "8000:8000" environment: - DATABASE_URL=postgresql://postgres:1234@postgresdb:5432/rustdb?sslmode=disable depends_on: - postgresdb volumes: rust_api_data: {}
排查与解决方案
1. 构建阶段无法访问Postgres容器
这是核心问题:docker-compose build过程中,rust_backend容器并未加入到Postgres所在的Docker网络,无法通过服务名postgresdb访问数据库。而sqlx的query!宏在编译时会主动连接数据库做SQL语法校验、类型推导,直接导致构建失败。
解决方式二选一:
- 临时使用本地数据库构建:构建时将
DATABASE_URL指向宿主机的Postgres实例,执行:
前提是宿主机已启动Postgres,且容器能通过DATABASE_URL=postgresql://postgres:1234@host.docker.internal:5432/rustdb?sslmode=disable docker-compose buildhost.docker.internal访问宿主机。 - 启用sqlx离线构建:
- 本地提前生成
sqlx-data.json文件:sqlx prepare --database-url postgresql://postgres:1234@localhost:5432/rustdb?sslmode=disable - 修改docker-compose中rust_backend的构建配置,传入离线构建参数:
rust_backend: # ...其他配置 build: context: . args: - SQLX_OFFLINE=true - 确保
Cargo.toml中sqlx依赖包含offline特性:sqlx = { version = "0.7", features = ["postgres", "runtime-tokio-native-tls", "offline"] }
- 本地提前生成
2. 运行阶段的服务就绪问题
即使构建成功,depends_on仅保证容器启动顺序,不代表Postgres已完成初始化并可接受连接。需要在rust_backend启动前等待Postgres就绪:
- 引入
wait-for-it脚本:- 下载
wait-for-it.sh脚本到项目根目录。 - 修改Dockerfile,将脚本复制到镜像并赋予执行权限:
COPY wait-for-it.sh /app/wait-for-it.sh RUN chmod +x /app/wait-for-it.sh - 修改docker-compose中rust_backend的启动命令:
rust_backend: # ...其他配置 command: ["/app/wait-for-it.sh", "postgresdb:5432", "--", "/app/rest_api"]
- 下载
3. 验证Docker网络连通性
若以上步骤仍有问题,手动验证网络:
- 启动Postgres容器:
docker-compose up -d postgresdb - 运行临时容器测试服务名解析与连接:
确认能ping通服务名,且Postgres能正常响应查询。docker run --rm --network $(basename $(pwd))_default alpine ping -c 3 postgresdb docker run --rm --network $(basename $(pwd))_default postgres:13.3 psql -h postgresdb -U postgres -d rustdb -c "SELECT 1;"
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

