ASP.NET容器连接PostgreSQL容器失败的问题排查
问题
我有一个基于ASP.NET Core的API,使用Npgsql连接PostgreSQL,API运行在Docker容器中。在Visual Studio通过Swagger运行时能正常连接数据库,但部署到容器后无法连接PostgreSQL,调用API端点时会触发该问题。
已尝试操作
查阅了大量相关帖子,认为问题与连接字符串有关,但尝试所有IP地址和容器名称均无效。
配置信息
ASP.NET项目的appsettings.json配置
"ConnectionStrings": { "PostgresDatabase": "Host=local_pgdb;Port=5432; Database=postgres; Username=user; Password=admin;MultipleActiveResultSets=true" },
PostgreSQL Docker Compose文件
version: "3.8" services: db: image: postgres container_name: local_pgdb restart: always ports: - "5432:5432" environment: POSTGRES_USER: user POSTGRES_PASSWORD: admin volumes: - local_pgdata:/var/lib/postgresql/data pgadmin: image: dpage/pgadmin4 container_name: pgadmin4_container restart: always ports: - "5050:80" environment: PGADMIN_DEFAULT_EMAIL: raj@nola.com PGADMIN_DEFAULT_PASSWORD: admin volumes: - pgadmin-data:/var/lib/pgadmin volumes: local_pgdata: pgadmin-data:
ASP.NET API Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app ENV ASPNETCORE_ENVIRONMENT Development ENV ASPNETCORE_URLS=http://+:80 FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["haymatlosApi.csproj", "."] RUN dotnet dev-certs https RUN dotnet restore "./haymatlosApi.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "haymatlosApi.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "haymatlosApi.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app EXPOSE 80/tcp COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "haymatlosApi.dll"]
Docker控制台错误信息
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3] 2023-08-23 17:45:53 Failed to determine the https port for redirect. 2023-08-23 17:45:55 warn: Microsoft.EntityFrameworkCore.Query[10102] 2023-08-23 17:45:55 The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. 2023-08-23 17:45:55 warn: Microsoft.EntityFrameworkCore.Query[10102] 2023-08-23 17:45:55 The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased. fail: Microsoft.EntityFrameworkCore.Database.Connection[20004] 2023-08-23 16:56:31 An error occurred using the connection to database 'postgres' on server ''. 2023-08-23 16:56:31 fail: Microsoft.EntityFrameworkCore.Query[10100] 2023-08-23 16:56:31 An exception occurred while iterating over the results of a query for context type 'haymatlosApi.haymatlosApi.Models.PostgresContext'. 2023-08-23 16:56:31 System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. 2023-08-23 16:56:31 ---> Npgsql.NpgsqlException (0x80004005): Failed to connect to [::1]:5432 2023-08-23 16:56:31 ---> System.Net.Sockets.SocketException (99): Cannot assign requested address
解决方案
从错误日志看,API容器在尝试连接[::1]:5432(本地回环地址),说明连接字符串中的容器名称未被正确解析,核心问题是API容器与PostgreSQL容器不在同一个Docker网络,无法互相访问。
1. 将API服务加入Docker Compose的同一网络
单独启动的API容器和PostgreSQL容器默认不在同一网络,需把API服务添加到现有Docker Compose文件中,确保所有服务共享同一个默认网络。修改后的Docker Compose文件如下:
version: "3.8" services: db: image: postgres container_name: local_pgdb restart: always ports: - "5432:5432" environment: POSTGRES_USER: user POSTGRES_PASSWORD: admin volumes: - local_pgdata:/var/lib/postgresql/data pgadmin: image: dpage/pgadmin4 container_name: pgadmin4_container restart: always ports: - "5050:80" environment: PGADMIN_DEFAULT_EMAIL: raj@nola.com PGADMIN_DEFAULT_PASSWORD: admin volumes: - pgadmin-data:/var/lib/pgadmin api: build: ./path/to/your/api-project # 替换为你的API项目目录(包含Dockerfile) container_name: haymatlos_api restart: always ports: - "80:80" environment: ASPNETCORE_ENVIRONMENT: Development depends_on: - db # 确保API在PostgreSQL启动后再启动 volumes: local_pgdata: pgadmin-data:
2. 修正连接字符串的Host配置
在Docker Compose网络中,容器通过服务名称互相访问更可靠,把连接字符串中的Host=local_pgdb改为Host=db(对应Compose中PostgreSQL的服务名):
"ConnectionStrings": { "PostgresDatabase": "Host=db;Port=5432;Database=postgres;Username=user;Password=admin;MultipleActiveResultSets=true" }
3. 重新构建并启动服务
执行以下命令更新服务:
# 停止现有服务 docker-compose down # 构建API镜像并启动所有服务 docker-compose up --build
额外排查点
- 检查PostgreSQL容器状态:执行
docker logs local_pgdb,确认数据库已正常启动并就绪。 - 验证API容器环境变量:进入API容器后执行
echo $ASPNETCORE_ENVIRONMENT,确保加载的是正确的配置文件。 - 测试容器间连通性:在API容器内安装
ping工具(apt-get update && apt-get install -y iputils-ping),执行ping db确认能连通PostgreSQL服务。
内容的提问来源于stack exchange,提问作者beriscen
相关产品推荐
相关产品推荐

