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