You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fly.io部署Docker应用无法连接PostgreSQL问题求助

解决Fly.io上.NET应用连接PostgreSQL的SSL握手异常问题

问题描述

在Fly.io上通过Docker部署.NET应用后,无法连接PostgreSQL数据库,本地运行一切正常。错误日志如下:

fail: Microsoft.EntityFrameworkCore.Database.Connection[20004]使用服务器上的数据库'dash007_reactivities?sslmode=disable'连接时出错 fail: Microsoft.EntityFrameworkCore.Query[10100]遍历上下文类型'Persistence.DataContext'的查询结果时发生异常。
System.InvalidOperationException: 引发了一个可能由瞬态故障导致的异常。
Npgsql.NpgsqlException (0x80004005): 执行SSL握手时发生异常

核心原因

Fly.io托管的PostgreSQL要求强制SSL连接,但当前生产环境的数据库连接字符串未配置SSL相关参数,导致握手失败。

解决方案

1. 修正生产环境连接字符串

在生成生产环境连接字符串时,添加SSL强制启用和信任服务器证书的参数:

services.AddDbContext<DataContext>(options =>
{
    var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    string connStr;

    if (env == "Development")
    {
        connStr = config.GetConnectionString("DefaultConnection");
    }
    else
    {
        var connUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
        connUrl = connUrl.Replace("postgres://", string.Empty);

        var pgUserPass = connUrl.Split("@")[0];
        var pgHostPortDb = connUrl.Split("@")[1];
        var pgHostPort = pgHostPortDb.Split("/")[0];
        var pgDb = pgHostPortDb.Split("/")[1];
        var pgUser = pgUserPass.Split(":")[0];
        var pgPass = pgUserPass.Split(":")[1];
        var pgHost = pgHostPort.Split(":")[0];
        var pgPort = pgHostPort.Split(":")[1];

        // 添加SSL参数
        connStr = $"Server={pgHost};Port={pgPort};User Id={pgUser};Password={pgPass};Database={pgDb};SSL Mode=Require;Trust Server Certificate=true;";
    }

    options.UseNpgsql(connStr);
});

2. (可选)使用Npgsql内置解析器简化URL处理

手动拆分DATABASE_URL容易出错,推荐用NpgsqlConnectionStringBuilder直接解析:

else
{
    var connUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
    var builder = new NpgsqlConnectionStringBuilder(connUrl);
    builder.SslMode = SslMode.Require;
    builder.TrustServerCertificate = true;
    connStr = builder.ToString();
}

注意:需确保项目已引用Npgsql NuGet包

3. 验证Fly.io配置

  • 确认fly.toml中private_network = true已开启(当前配置已满足),保证应用与PostgreSQL实例在同一私有网络内。
  • 通过fly secrets list命令检查DATABASE_URL环境变量是否正确配置。

补充说明

Fly.io的PostgreSQL使用自签名SSL证书,因此需要添加Trust Server Certificate=true参数绕过证书验证,否则会因证书不被信任导致连接失败。

内容的提问来源于stack exchange,提问作者Davit Shavliashvili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 20:57:12