ASP.NET Core Web API通过Docker Compose连接PostgreSQL启动失败排查
问题:Docker Compose部署EF Core应用时API启动崩溃(数据库连接拒绝)
执行docker-compose up -d部署应用时,API在启动阶段崩溃,非生产环境下尝试通过EF Core迁移数据库时出现以下错误:
2024-05-15 17:24:18 Unhandled exception. Npgsql.NpgsqlException (0x80004005): Failed to connect to 192.168.208.2:5432 2024-05-15 17:24:18 ---> System.Net.Sockets.SocketException (111): Connection refused 2024-05-15 17:24:18 at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 2024-05-15 17:24:18 at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 2024-05-15 17:24:18 at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) 2024-05-15 17:24:18 at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|213_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) 2024-05-15 17:24:18 at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 2024-05-15 17:24:18 at Npgsql.UnpooledDataSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 2024-05-15 17:24:18 at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|42_0(Boolean async, CancellationToken cancellationToken) 2024-05-15 17:24:18 at Npgsql.NpgsqlConnection.Open() 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) 2024-05-15 17:24:18 at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) 2024-05-15 17:24:18 at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) 2024-05-15 17:24:18 at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists() 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.GetAppliedMigrations() 2024-05-15 17:24:18 at Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Internal.NpgsqlMigrator.Migrate(String targetMigration) 2024-05-15 17:24:18 at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade) 2024-05-15 17:24:18 at Program.<Main>$(String[] args) in /src/QuizyZunaAPI.Api/Program.cs:line 31
Docker Compose主配置
version: '3.4' services: quizyzuna-db: container_name: Database image: postgres:alpine restart: always environment: - POSTGRES_DB=quizyzunadb - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres volumes: - ./.containers/database:/var/lib/postgressql/data ports: - 5432:5432 quizyzuna-api: container_name: API image: ${DOCKER_REGISTRY-}quizyzunaapi build: context: src/ depends_on: - quizyzuna-db
Docker Compose覆盖配置
version: '3.4' services: quizyzuna-api: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_HTTP_PORTS=8080 - ASPNETCORE_HTTPS_PORTS=8081 - ConnectionStrings__Database=Host=Database;Username=postgres;Password=postgres;Database=quizyzunadb; ports: - "8080" - "8081" volumes: - ${APPDATA}/Microsoft/UserSecrets:/home/app/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/home/app/.aspnet/https:ro
已排查点:移除本地连接字符串,使用Docker配置的连接字符串;本地可通过DBeaver连接数据库;已排除连接字符串中主机设为localhost的错误。
解决思路
修复数据库数据目录路径:主配置中volumes的目标路径
/var/lib/postgressql/data存在拼写错误,正确路径应为/var/lib/postgresql/data(去掉多余的s)。该错误会导致数据库初始化失败,无法正常提供服务。等待数据库服务就绪后启动API:
depends_on仅保证容器启动顺序,不确保数据库服务完全就绪。可通过两种方式处理:- 在API启动脚本中加入等待逻辑,比如使用
wait-for-it.sh脚本检测Database:5432端口连通后再启动应用 - 在EF Core连接逻辑中添加重试机制,例如用Polly库实现数据库连接的自动重试,避免因短暂未就绪导致启动失败
- 在API启动脚本中加入等待逻辑,比如使用
检查数据库容器状态:执行
docker logs Database查看数据库启动日志,确认是否存在初始化错误(如权限问题、数据目录挂载失败等)。验证容器网络连通性:进入API容器执行
ping Database或telnet Database 5432,确认两个容器在同一Docker网络下是否能正常通信。调整迁移执行时机:不在应用启动时自动执行迁移,改为手动执行:
docker-compose run quizyzuna-api dotnet ef database update待迁移完成后再启动API服务。
内容的提问来源于stack exchange,提问作者Lambert Maxime
相关产品推荐
相关产品推荐

