Docker-Compose运行.NET应用时MigrateAsync抛出SocketException问题
问题现象
.NET应用通过IHostedService启动时执行数据库迁移,本地IIS/HTTPS启动正常,但Docker Compose部署时,await dbContext.Database.MigrateAsync()抛出System.Net.Sockets.SocketException (00000005, 0xFFFDFFFF): Name or service not known错误。
解决方案
1. 正确配置连接字符串的主机地址
Docker Compose默认会创建内部网络,服务名可作为容器间访问的主机名。你的数据库服务名是alledrogo.database,因此连接字符串的Host必须设置为该值,无需额外指定端口(PostgreSQL默认5432):
Host=alledrogo.database;Database=alledrogo;Username=postgres;Password=postgres;Port=5432
注意:不要使用容器名Postgres或localhost——localhost在容器内部指向自身,容器名并非默认的可解析主机名,只有服务名在Compose网络中自动生效。
2. 添加容器启动依赖与数据库健康检查
应用容器启动时,数据库可能还未完成初始化,导致连接失败。修改docker-compose.yml,添加健康检查并让应用容器等待数据库就绪:
services: alledrogo.api: image: alledrogo.api container_name: Api build: context: . dockerfile: Bootstrapper/AlledrogO.Bootstrapper/Dockerfile ports: - "5000:8080" depends_on: alledrogo.database: condition: service_healthy # 等待数据库健康检查通过后启动应用 alledrogo.database: image: postgres:latest container_name: Postgres environment: - POSTGRES_DB=alledrogo - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres volumes: - ./.containers/alledrogo-db:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d alledrogo"] interval: 5s timeout: 5s retries: 5
3. 验证连接字符串的注入正确性
确保Docker环境下应用使用的是正确的连接字符串,建议通过环境变量传递(而非硬编码本地配置)。可在DatabaseInitializer中临时添加日志输出连接字符串(仅调试用),确认Host部分为alledrogo.database:
_logger.LogInformation("Current connection string: {ConnStr}", dbContext.Database.GetConnectionString());
4. 确认Docker网络一致性
Docker Compose默认会为所有服务创建一个自定义网络,执行以下命令检查两个容器是否在同一网络:
# 查看当前Compose项目的网络 docker network ls # 检查容器所属网络 docker inspect Api | grep Networks docker inspect Postgres | grep Networks
若存在自定义网络配置,需确保alledrogo.api和alledrogo.database服务都加入同一个网络。
内容的提问来源于stack exchange,提问作者Hubert Damaszko

