简体   繁体   English

无法将Npgsql连接到在Docker上运行的Postgres DB

[英]Cannot connect Npgsql to Postgres DB running on Docker

I have a docker container with a .NET app with the following code: 我有一个带有.NET应用程序的Docker容器,其代码如下:

var pgsql = OpenDbConnection("Server=localhost;Database=postgres;Username=postgres;Password=MyPass;Port=5432");

private static NpgsqlConnection OpenDbConnection(string connectionString)
        {
            NpgsqlConnection connection;
            Console.Error.WriteLine("Connecting to DB");

            while (true)
            {
                try
                {
                    connection = new NpgsqlConnection(connectionString);
                    connection.Open();
                    break;
                }
                catch (SocketException e)
                {
                    Console.WriteLine("{0} Exception caught.", e);
                    Thread.Sleep(1000);
                }
                catch (DbException)
                {
                    Console.Error.WriteLine("Waiting for db - db error");
                    Thread.Sleep(1000);
                }
            }

            return connection;
        }

I have a different container with the official Postgres container, that I started with command 我有一个与官方Postgres容器不同的容器,我从命令开始

docker run --name localpg -e POSTGRES_PASSWORD=MyPass -d postgres -p 5432:5432

Now I can connect from pgAdmin with host localhost , user&password postgres and password MyPass . 现在,我可以从pgAdmin连接到主机localhost ,user&password postgres和密码MyPass

However, if I try to run the .NET code above from the same computer with command docker run worker , I get this exception: 但是,如果我尝试使用docker run worker命令从同一台计算机上运行上述.NET代码,则会出现此异常:

System.Net.Sockets.SocketException: Unknown error -1
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout)
   at Npgsql.ConnectorPool.Allocate(NpgsqlConnection conn, NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnection.OpenInternal()
   at Worker.Program.OpenDbConnection(String connectionString) Exception caught.

Any thoughts? 有什么想法吗?

EDIT 编辑

Following Dan's recommendation I changed the connection string to 按照Dan的建议,我将连接字符串更改为

var pgsql = OpenDbConnection("Server=localpg;Database=postgres;Username=postgres;Password=MyPass;Port=5432");

but still doesn't work ( InternalSocketException: No such device or address ). 但仍然不起作用( InternalSocketException: No such device or address )。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
ad8fa68b5dab        bridge              bridge              local
984027aadc2a        host                host                local
5604001734fa        none                null                local

Starting app container with docker run worker (no compose used). 使用docker run worker启动应用程序容器(不使用compose)。

Each container has its own localhost 每个容器都有自己的本地主机

You have two containers here, one running your .Net app, and one running your Postgres database. 这里有两个容器,一个运行.Net应用程序,另一个运行Postgres数据库。 From the perspective of your .Net app container, there is no Postgres running on the local host (the .Net container), yet you are trying to connect to localhost: 从.Net应用程序容器的角度来看,本地主机(.Net容器)上没有运行Postgres,但是您正在尝试连接到localhost:

var pgsql = OpenDbConnection("Server=localhost;Database=postgres; ...");

Your two containers are separate and each one has their own localhost. 您的两个容器是分开的,每个容器都有自己本地主机。 To connect to the Postgres container, use its name as if it were a hostname. 要连接到Postgres容器,请使用其名称,就像它是主机名一样。 Judging by the docker run command you posted in your question, you should be using: 从您在问题中发布的docker run命令来看,您应该使用:

var pgsql = OpenDbConnection("Server=localpg;Database=postgres; ...");

Your PC also has its own localhost 您的PC也有自己的本地主机

The reason you can connect to Postgres on localhost:5432 using pgAdmin is that you have exported port 5432 from Docker to the outside host (the computer you are running Docker on). 您可以使用pgAdmin连接到localhost:5432上的Postgres的原因是,您已将端口5432从Docker导出到外部主机(在其上运行Docker的计算机)。 That is what -p 5432:5432 is doing in your docker run command. 这就是-p 5432:5432docker run命令中正在执行的操作。

On that system's localhost, port 5432 is bound to Postgres in the container. 在该系统的localhost上,端口5432绑定到容器中的Postgres。 (This is a third localhost, separate from the localhost as seen from inside of each of your containers.) (这是第三个本地主机,从每个容器内部看,它与本地主机是分开的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM