Rust容器编译时可连Postgres,运行时连接被拒绝求助
问题解决:Rust + sqlx 编译时连接正常,容器运行后无法连接Postgres
问题根源
你在构建阶段给backend配置了network: host,这让构建容器直接使用宿主机网络,能访问到宿主机端口映射的Postgres(或宿主机本地的Postgres),所以sqlx的query!()宏编译校验能通过。但容器运行时,backend默认处于docker-compose的桥接网络中,此时localhost指向容器自身,而非宿主机或postgres服务容器,自然会出现连接拒绝的错误。
解决方案
方案1:修改数据库连接地址为服务名(推荐)
直接修改backend的.env文件中的DATABASE_URL,把地址部分从localhost替换为docker-compose中postgres服务的名称postgres:
DATABASE_URL=postgres://用户名:密码@postgres:5432/数据库名
docker-compose会自动在内部网络中解析服务名到对应容器的IP,这样backend容器就能正常连接postgres服务。
方案2:运行阶段也使用host网络(不推荐)
如果因为特殊需求必须用宿主机网络,可以给backend服务添加network: host配置,同时移除ports映射(host网络下容器端口直接绑定宿主机):
backend: build: context: backend dockerfile: Dockerfile network: host env_file: - backend/.env network: host # 添加运行阶段的host网络配置 depends_on: - postgres
此时.env中的DATABASE_URL可以保持localhost,但要注意宿主机的5432端口没有被其他进程占用,且postgres容器的端口映射正常。
额外注意事项
depends_on仅保证postgres容器先启动,不确保Postgres服务已完全就绪。可以给postgres添加健康检查,让backend在数据库就绪后再启动:
同时修改backend的postgres: image: postgres:16.1 restart: on-failure ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data env_file: - .pg.env healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 5depends_on:depends_on: postgres: condition: service_healthy- 若不想在构建阶段使用
network: host,可以创建自定义网络,让构建容器和postgres服务都加入该网络,这样构建时也能通过服务名连接Postgres,避免依赖宿主机网络:version: "3.9" networks: app-network: driver: bridge services: postgres: ... networks: - app-network backend: build: context: backend dockerfile: Dockerfile networks: - app-network ... networks: - app-network
内容的提问来源于stack exchange,提问作者lucasfelber
相关产品推荐
相关产品推荐

