Home > Mobile >  ASP.NET Core 6 cannot resolve database name when running in docker container (in WSL2)
ASP.NET Core 6 cannot resolve database name when running in docker container (in WSL2)

Time:08-18

I am dockerizing an ASP.NET Core 6 application step by step as follows:

  • I have set up WSL2 in Windows 10 and installed Racher Desktop. This allows running docker commands as if run in the WSL2 guest
  • I have run a Postgresql container and it is accessible to both host (Windows) pgAdmin and for the ASP.NET Core when run from Visual Studio:
docker run -d -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -p 5433:5432 postgres

(port 5432 was hijacked by some service before installing the Postgres and I had to use another port).

When running from Visual Studio, the application uses the following connection string:

Host=localhost:5433; Database=foo-next; Username=postgres; Password=postgres; Timeout=300; CommandTimeout=300

I have created a Dockerfile and a docker image for the application. When running I receive the following error:

Unhandled exception. System.Net.Internals.SocketExceptionFactory ExtendedSocketException (00000005, 0xFFFDFFFF): Name does not resolve
   at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch)
   at System.Net.Dns.<>c.<GetHostEntryOrAddressesCoreAsync>b__33_0(Object s, ValueStopwatch stopwatch)
   at System.Net.Dns.<>c__DisplayClass39_0`1.<RunAsync>b__0(Task <p0>, Object <p1>)
   at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Npgsql.TaskExtensions.ExecuteWithTimeout[TResult](Func`2 func, NpgsqlTimeout timeout, CancellationToken cancellationToken)
   at Npgsql.TaskExtensions.WithCancellation[T](Task`1 task, CancellationToken cancellationToken)
   at Npgsql.TaskExtensions.WithTimeout[T](Task`1 task, NpgsqlTimeout timeout)
   at Npgsql.Internal.NpgsqlConnector.ConnectAsync(NpgsqlTimeout timeout, CancellationToken cancellationToken)
   at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|191_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.UnpooledConnectorSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.ExistsAsync(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)

I interpret this as the application not being able to resolve postgres hostname. I have checked if Postgres containers and the .NET Core one run in the same network and they seem they do, but some attributes are missing for my app network metadata:

Wehn running in the container, the application uses the following connection string:

Host=postgres:5433; Database=foo-next-docker; Username=postgres; Password=postgres; Timeout=300; CommandTimeout=300
docker inspect postgres -f "{{json .NetworkSettings.Networks }}"
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"343ece236719b94d53df0afe1ab0d405a19102002f67ea60a1914016d4e4f96b","EndpointID":"9c3740b300caaf50f86731f00530dce62b386b56ccc2fe3da96c4cb677dcb42d","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}}

docker inspect foonextapp -f "{{json .NetworkSettings.Networks }}"
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"343ece236719b94d53df0afe1ab0d405a19102002f67ea60a1914016d4e4f96b","EndpointID":"","Gateway":"","IPAddress":"","IPPrefixLen":0,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"","DriverOpts":null}}

The same result I get when explicitly running the container attached to the bridge network:

docker run -p 8080:80 --name fooapp fooapp --network=bridge

Not sure if it provides more information, but the whole docker network list is the following:

docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
343ece236719   bridge     bridge    local
df0c354db7cf   host       host      local
6efb481fc02b   minikube   bridge    local
23bdb658109a   none       null      local

Any suggestions about what to try next in order to make the app running in local container resolve the database container name?

Note: all commands were run in Windows.

CodePudding user response:

You need to specify a network-alias, because a container’s hostname defaults to be the container’s ID.

In PowerShell:

docker network create app
docker run -dp 5433:5432 `
    -v pgdata:/var/lib/postgresql/data `
    -e POSTGRES_PASSWORD=postgres `
    --network app --network-alias postgres `
    postgres
docker run -dp 8080:80 --network app fooapp
  • Related