Visual Studio 无法使用IP地址连接到Docker PostgresSQL

dy1byipe  于 2023-08-07  发布在  Docker
关注(0)|答案(1)|浏览(201)

我正在使用C# Visual Studio 2022/.NET6。当我尝试使用容器IP地址172.17.0.2在Docker容器上连接PostgreSQL时,出现异常:

"Host=172.17.0.2:5432;Database=postgres;Username=postgres;Password=xxxxx"

字符串
但是当我使用`localhost '连接时,连接成功:

"Host=localhost:5432;Database=postgres;Username=postgres;Password=xxxxx"

  • 如何将PostgreSQL安装为Docker容器 *
Step 1 - Install Postgres

docker pull postgres
docker run --name gb-postgres -p 5432:5432 -e POSTGRES_PASSWORD=xxxxxx -d postgres

Step 2 - Once Postgres is installed you need to find out your instance IP address

Run
docker ps

copy the {id  of the container} of the container and run

docker inspect {id  of the container}

copy the IPAddress of the container

Step 3 - Configure API

Use IP address in your Program.cs

  • 异常 *
Npgsql.NpgsqlException (0x80004005): Failed to connect to 172.17.0.3:5432
 ---> System.TimeoutException: Timeout during connection attempt
   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, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|203_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.PoolingDataSource.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.PoolingDataSource.<Get>g__RentAsync|28_0(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.Open()
   at Program.Main(String[] args) in D:\data\code\Dust-IO\388013gb3\cloud\API\GB3API\ConsoleApp1\Program.cs:line 14

  • C#程序 *
using System;
using Npgsql;

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "Host=172.17.0.2;Database=GB3;Username=postgres;Password=xxxxx";

        using (var connection = new NpgsqlConnection(connectionString))
        {
            try
            {
                connection.Open();
                Console.WriteLine("Connected to PostgreSQL database.");

                // Perform database operations here

                connection.Close();
                Console.WriteLine("Connection closed.");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
        }

        Console.ReadLine();
    }
}


甚至当我尝试使用Visual Studio 2022扩展Npgsql PostgreSQL Integration连接时,我也会收到错误Exception while connecting。当我尝试使用VS Code扩展名PostgreSQL by Chris Kolkman连接时,我得到一个连接ETIMEDOUT 172.17.0.2:5432的错误。

  • docker检查 *
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "d9371cf11864c75a9c35d03ce24bf90bb78af8f44b43e6336b0630a6d79d9503",
                    "EndpointID": "b235ae6eb713404f9fbbcd35453acb6e9dcb213ad6d51fa8809272912a569e15",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }

f5emj3cl

f5emj3cl1#

实际上,docker inspect IP地址基本上是无用的。你只能在一个非常特定的Docker配置中使用它(在本地Linux主机上运行Docker引擎,没有Docker Desktop)。从来没有理由去查它,在这种情况下你也不需要它。
一种更健壮的方法是使用docker run -p选项将端口从容器发布到主机,然后访问该端口。这就是你在你的设置中看到的:您正在连接到Host=localhost和第一个docker run -p端口号。这适用于原生Linux,Docker Desktop,可能还有一两个其他设置。
由此得出的一个推论是,连接字符串将是不同的,如果您的程序是在一个容器中运行或没有,你不能真的把它放在源代码一样。从容器外的主机,您需要localhost和发布的端口号;从同一个Docker网络上的另一个容器,你需要另一个容器的名称作为主机名和标准PostgreSQL端口5432(这里忽略-p端口Map)。环境变量是提供这些特定于环境的设置的一种方便方法。
如果出于某种原因需要IP地址而不是主机名(您在注解中建议),则localhost被定义为127.0.0.1。大多数客户端库几乎都接受DNS名称或IP地址。
(At在技术层面,docker inspect IP地址仅在单个Linux主机中定义。在直接运行Docker引擎的原生Linux系统上,ifconfig将向您显示Docker内部网络接口,您可以连接到它们。但是,如果您在另一台主机上,则根本无法访问这些IP地址。Docker Desktop始终运行Linux VM,即使在原生Linux上也是如此,并且无法从该VM外部访问Docker内部地址。

相关问题