2

I have a docker container with a .NET app with the following code:

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

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.

However, if I try to run the .NET code above from the same computer with command docker run worker, I get this exception:

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

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

but still doesn't work (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).

1 Answer 1

3

Each container has its own localhost

You have two containers here, one running your .Net app, and one running your Postgres database. 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:

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. Judging by the docker run command you posted in your question, you should be using:

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

Your PC also has its own localhost

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). That is what -p 5432:5432 is doing in your docker run command.

On that system's localhost, port 5432 is bound to Postgres in the container. (This is a third localhost, separate from the localhost as seen from inside of each of your containers.)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, very useful. However, changing server to "localpg" doesn't work. I get System.AggregateException: One or more errors occurred. (No such device or address) ---> System.Net.Internals.InternalSocketException: No such device or address. This is the docker ps output: 0ff98e5b06d8 postgres "/docker-entrypoint.s" About an hour ago Up 38 minutes 0.0.0.0:5432->5432/tcp localpg
Can you update your question to show how you are starting the app container also? And you are just using docker run, or are you using any other tooling, such as docker-compose? Lastly, if you can include the output from docker network ls. It's best to put this in the question, not in comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.