'System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString') asp.net Core Docker-compose

I have a dockerized asp.net Core application trying to connect to a mySql Database. Both are running inside a docker-compose. When I test the connection to a local Database without Docker, my code is working fine, but when I deploy it on a Vm inside docker-compose and that I call one of my controller, I get this error : System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString') . Here is my docker-compose :

version: '3'
services:
  dbgil:
   container_name: dbgil
   image: mysql
   restart: always
   ports:
     - 3306:3306
   environment:
     MYSQL_ROOT_PASSWORD: root
   volumes:
     - dbdata:/var/lib/mysql
  webserver:
    depends_on:
      - dbgil
    image: lionelquirynen/gillesquirynensys:latest
    ports:
      - "8021:80"
    links:
      - dbgil
volumes:
    dbdata:

And here is my startup in my asp.net core application :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GillesQuirynenSys.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace GillesQuirynenSys
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql("server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MySqlDbContext context)
        {
            context.Database.EnsureCreated();
            var databaseCreator = context.GetService<IRelationalDatabaseCreator>();
            databaseCreator.CreateTables();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}


I first had my connection string in my appsettings.json but I was getting the same error so I tried to hardcode it but it did not change anything. Has anyone any ideas? It seems like my configuration is working fine (at least, it is locally without Docker).

PS: Here is the DockerFile of my asp.net Core application before pushing it to DockerHub :

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

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 ["GillesQuirynenSys/GillesQuirynenSys.csproj", "GillesQuirynenSys/"]
RUN dotnet restore "GillesQuirynenSys/GillesQuirynenSys.csproj"
COPY . .
WORKDIR "/src/GillesQuirynenSys"
RUN dotnet build "GillesQuirynenSys.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "GillesQuirynenSys.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "GillesQuirynenSys.dll"]


Solution 1:[1]

I'm glad my answer helped. So basicaly in the docker container, the server name of MySQL db is the same as the service name declared in docker-compose.yml file.

One more note to your code: Instead of this:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql("server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"));
        }

-> where you hard-code your connection string

Try this:

      public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
        }

And adjust your appsettings.json file - for production (docker container) build, you will have:

{
  "ConnectionStrings": {
    "DefaultConnection": "server=dbgil;port=3306;database=test;user=root;password=root;convert zero datetime=True"
  }
...
}

And in appsettings.Development.json, you will have a connection string for Development mode (your localhost):

{
  "ConnectionStrings": {
    "DefaultConnection": "server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"
  }
...
}

Solution 2:[2]

Try using this, it works:

"ConnectionStrings": {
  "ShopOnlineConnection": "server:(localdb)\\MSSQLLocalDB;database=ShopOnline;Trusted_Connection:True;"
},

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jakub Kozera
Solution 2 Suraj Rao