Naf*_*tis 4 postgresql docker asp.net-core-webapi .net-6.0
我正在尝试创建一个 docker-compose 脚本来启动具有 PostgreSql 数据库和 ASP.NET Core 6 Web API 的堆栈。为了测试该场景,我使用默认模板创建了一个新的 ASP.NET Core 6 Web API。然后我添加了 NuGet 包Npgsql(6.0.3)和一个仅查询数据库引擎版本的示例控制器,例如:
[ApiController]
[Produces("application/json")]
public class TestController : Controller
{
private readonly IConfiguration _config;
public TestController(IConfiguration config)
{
_config = config;
}
[HttpGet("api/dbversion")]
public IActionResult GetVersion()
{
using NpgsqlConnection conn = new(_config.GetConnectionString("Default"));
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT version();";
return Ok($"Version: {cmd.ExecuteScalar() as string}");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我为此 API 创建了 Docker 映像,并编写了一个 docker-compose 脚本,如下所示:
version: '3.7'
services:
test-db:
image: postgres
# explicit container name
# another approach using hostname: https://stackoverflow.com/questions/68701716/docker-compose-postgres-connection-refused
container_name: test-db
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
ports:
- 5433:5432
networks:
- test-network
test-api:
image: MYREPONAME/test-api:0.0.1
ports:
- 5154:80
depends_on:
- test-db
environment:
- CONNECTIONSTRINGS__DEFAULT=User ID=postgres;Password=postgres;Host=test-db;Port=5433;Database=postgres
networks:
- test-network
networks:
test-network:
driver: bridge
Run Code Online (Sandbox Code Playgroud)
在这里,我使用官方postgres映像,设置默认凭据,将服务重定向到组合堆栈中的端口 5433,并从同一网络内的 API 使用它。我正在覆盖脚本中的连接字符串,使用容器名称 ( test-db) 作为主机名;localhost在 Docker 网络中不会是一个选项(例如参见此处和此处)。
当我从 Ubuntu 主机触发此脚本时,我可以访问端口 5433 处的数据库服务和 localhost:5154/swagger/index.html 处的 Web API。然而,当我运行应该连接到数据库的操作时,即使我可以清楚地看到数据库服务 IP 和端口,我也会收到连接拒绝错误:
"Exception":"Npgsql.NpgsqlException (0x80004005): Failed to connect to 172.27.0.2:5433
---\u003E System.Net.Sockets.SocketException (111): Connection refused
at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.\u003COpen\u003Eg__OpenCore|191_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.ConnectorPool.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.ConnectorPool.\u003CGet\u003Eg__RentAsync|28_0(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.\u003COpen\u003Eg__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlConnection.Open()
...
Run Code Online (Sandbox Code Playgroud)
当一个容器连接到桥接网络上的另一个容器时,您可以使用容器端口。不是主机上的映射端口。所以你的连接字符串应该是
CONNECTIONSTRINGS__DEFAULT=User ID=postgres;Password=postgres;Host=test-db;Port=5432;Database=postgres
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4749 次 |
| 最近记录: |