1

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"]
1
  • 1
    If I remeber correctly, you should use the name of you mysql service, so dbgil instead of localhost in the connection string running in a docker container. Try replacing this piece of code: server=localhost; to "server=dbgil; Commented May 16, 2020 at 8:31

2 Answers 2

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"
  }
...
}
Sign up to request clarification or add additional context in comments.

3 Comments

I know I know, I hardcoded it because I was getting the error of null exception but now I changed it back :) Anyway thank you, it works fine now !
sure, could you accept my answer since its the correct solution ?:P
I just did ;) Have a nice day :)
0

Try using this, it works:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.