I have 2 docker containers as shown below. I can connect to PostgresSQL in docker by calling Test.Main()
method without exception through a net6.0 C# Console App. But when I try to call Test.Main()
from ASP.NET docker container I am unable to connect to PostgresSQL and get the exception Failed to connect to 127.0.0.1:5432
:
{Npgsql.NpgsqlException (0x80004005): Failed to connect to 127.0.0.1:5432
---> 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, Boolean isFirstAttempt)
at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|215_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 APIDA.DBModels.Test.Main() in Version.cs:line 34}
C:UsersHT>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bdc65451aeda gb3api:dev "tail -f /dev/null" 17 minutes ago Up 16 minutes 0.0.0.0:49160->80/tcp, 0.0.0.0:49159->443/tcp GB3API
95b6a289f4a8 postgres "docker-entrypoint.s…" 47 minutes ago Up 47 minutes 0.0.0.0:5432->5432/tcp gb-postgres
ASP.NET DockerFile is
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["GB3API/GB3API.csproj", "GB3API/"]
RUN dotnet restore "GB3API/GB3API.csproj"
COPY . .
WORKDIR "/src/GB3API"
RUN dotnet build "GB3API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "GB3API.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "GB3API.dll"]
Test.Main
public class Test
{
public static void Main()
{
string connectionString = "Host=127.0.0.1;Database=postgres;Username=postgres;Password=xxxxx";
// Create a new PostgreSQL connection
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
try
{
// Open the connection
connection.Open();
// Check if the connection is open
if (connection.State == System.Data.ConnectionState.Open)
{
Console.WriteLine("Connected to PostgreSQL!");
// Perform your database operations here
// Close the connection when you're done
connection.Close();
Console.WriteLine("Connection closed.");
}
else
{
Console.WriteLine("Failed to open the connection.");
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
Console.ReadLine();
}
}
2
Answers
As it is mentioned in the error message, you application tries to connect to localhost:
The database in a different docker, which has an IP different from 127.0.0.1. You have to use the url:
to connect to your database, where
gb-postgres
is the name of the docker where postgresql is running.For app running in the container
127.0.0.1
will be the container itself which obviously does not have the database instance running. One way to handle this is to run both containers inside the same docker network and use the name resolution (i.e.Host=gb-postgres;Port=5432;
), the easiest way would be by usingdocker-compose
– see this answer.If your host OS (the one running the docker) Windows you can use
host.docker.internal
to reach outside the container i.e.Host=host.docker.internal;Port=5432;
(not sure about out of the box support on Linux but there are surely workarounds)