.Net Core docker container unable to connect to MySQL docker container

0

I have a mysql database hosted on a docker container. I am able to connect to the mysql database(hosted on a docker container) using dbeaver client application on my windows 10 machine. I am however not able to connect to it from my .Net core application deployed on another docker container. I get a Unable to connect to any of the specified MySQL hosts. error.

What could I be missing?

Appsettings.json:

  "ConnectionStrings": {
    "InstaTranscribeDBConnection": "server=localhost;port=3306;database=wordpress;user=root;password=SomePassword;"
  },

Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["server/InstaTranscribe.Server.csproj", "server/"]
COPY ["client/InstaTranscribe.Client.csproj", "client/"]
RUN dotnet restore "server/InstaTranscribe.Server.csproj"
COPY . .
WORKDIR "/src/server"
RUN dotnet build "InstaTranscribe.Server.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "InstaTranscribe.Server.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "InstaTranscribe.Server.dll"]
RUN chmod +x ./entrypoint.sh
CMD /bin/bash ./entrypoint.sh

entrypoint.sh:

#!/bin/bash

set -e
run_cmd="dotnet run --server.urls http://*:80"    
until dotnet ef database update; do
>&2 echo "SQL Server is starting up"
sleep 1
done    
>&2 echo "SQL Server is up - executing command"
exec $run_cmd

StackTrace:

Unhandled exception. System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call.
 ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.
   at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, Int32 startTickCount, ILoadBalancer loadBalancer, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/ServerSession.cs:line 474
   at MySql.Data.MySqlClient.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs:line 741
   at MySql.Data.MySqlClient.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs:line 396
   at MySql.Data.MySqlClient.MySqlConnection.Open() in /_/src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs:line 362
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlRelationalConnection.Open(Boolean errorsExpected)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext c, TState s)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
mysql
docker
asp.net-core
.net-core
asked on Stack Overflow Nov 10, 2020 by Ajit Goel

1 Answer

0

You will need more than one docker instances running

  1. .NET Core
  2. MySQL

More over they need to be part of the same network.

It's easier to provision a private network between two docker containers if you are using docker-compose file.

A sample would look like below:

version: '3'
services:
  moviedb:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: masteringdocker
      MYSQL_DATABASE: MvcMovieContext
      MYSQL_USER: moviedbadmin
      MYSQL_PASSWORD: masteringdocker
    volumes:
      - ./MvcMovie/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
  web:
    build: .
    restart: always
    ports:
      - "8000:80"
    depends_on:
      - moviedb
      - cache

The above will create a default network and put the two containers on it. But if you want better control on the network you could add below section.

networks:
  public_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: ${NETWORK_SUBNET}

And update each service moviedb and web to use this network using the below section:

networks:
  public_net:
     ipv4_address: ${HA_PROXY_IP}

HA_PROXY_IP is in the .env file

HA_PROXY_IP=192.168.0.99

This should get you started. You'll have to take care of multiple folder intricacies and place your docker-compose.yml and Dockerfile at the right places for everything to work smoothly.

answered on Stack Overflow Nov 10, 2020 by Ziaullah Khan

User contributions licensed under CC BY-SA 3.0