skip to Main Content

I have setup Docker with an ASP.NET Core 8 MVC application using Docker compose. There are two containers according to my compose.yaml, one is for the MySQL database (volume) and one for server. I managed to setup both containers and be able to interact with the database in the Docker volume using docker exec. The data get loaded from the .sql which lived in local directory.

However, the problem I face at the moment is I can’t connect my application to the database in the Docker.

PS: my Dockerfile is the default one from running docker init.

compose.yaml

services:
  database:
    image: mysql:latest
    ports: 
       - 3306:3306
    volumes:
       - ./sql-script:/docker-entrypoint-initdb.d
       - datafiles:/var/lib/mysql
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
        MYSQL_USER: ${USER}
        MYSQL_PASSWORD: ${PASSWORD}
        MYSQL_DATABASE: ${DB}
  server:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - database
    ports:
      - 8080:8080 
    environment:
      - DBHOST=database
      - ASPNETCORE_ENVIRONMENT=Development
    restart: always
    develop:
        watch:
         - action: rebuild
           path: .
volumes:
  datafiles:

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<myDatabaseContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("myDatabase") ?? throw new InvalidOperationException("Connection string 'myDatabase' not found.")));

According to my understanding, I’m still not sure about how Docker read application config files.

  1. launchSettings.json – this file will work only in Development mode and directly related to the play button in Visual Studio. In my case, this file can be ignored.
  2. appsettings.json – still not sure about this one, if it get call or not?
  3. appsettings.Development.json – This is what my compose.yaml called. I assume that when I define ASPNETCORE_ENVIRONMENT=Development, this is the file that get loaded.

At the moment, I have defined my connectionStrings inside appsettings.json which looks like this

"ConnectionStrings": {
    "myDatabase" : "Server=localhost,3306; Database=myDb; User=admin; Password=pass;"
}

Please correct if I’m wrong, if I set ASPNETCORE_ENVIRONMENT=Development in the compose.yaml, does this means all the app config file will get read from appsettings.Devlopment.json and NOT from appsettings.json.

Second question: when the appsettings.json will get called and not appsettings.Development.json? and where do I define the instruction for it to call different config file?

2

Answers


  1. Your database server runs on the host named database as you define in the environment variable DBHOST, but in you connection string you try to connect to localhost. Change you ConnectionString and it should work

    "ConnectionStrings": {
         "myDatabase" : "Server=database,3306; Database=myDb; User=admin; Password=pass;"
    }
    
    Login or Signup to reply.
  2. Just to elaborate on the config first:

    How does Docker read config from .NET application?

    Docker does not read config from .NET application, .NET application reads config based on how configuration providers are set up.

    As per docs default in your case would be:

    The initialized WebApplicationBuilder (builder) provides default configuration for the app in the following order, from highest to lowest priority:

    1. Command-line arguments using the Command-line configuration provider.
    2. Non-prefixed environment variables using the Non-prefixed environment variables configuration provider.
    3. User secrets when the app runs in the Development environment.
    4. appsettings.{Environment}.json using the JSON configuration provider. For example, appsettings.Production.json and appsettings.Development.json.
    5. appsettings.json using the JSON configuration provider.
    6. A fallback to the host configuration.

    i.e. all configuration sources are added hierarchically (based on the environment), so this:

    if I set ASPNETCORE_ENVIRONMENT=Development in the compose.yaml, does this means all the app config file will get read from appsettings.Devlopment.json and NOT from appsettings.json.

    is not fully correct, in case of ASPNETCORE_ENVIRONMENT=Development both files will be read (if both are present in the container), appsettings.Devlopment.json will have higher precedence, i.e. if some key is present in both the one from appsettings.Devlopment.json will be used.

    As for your specific issue, in the following:

    "ConnectionStrings": {
        "myDatabase" : "Server=localhost ..."
    }
    

    localhost will mean the container with application itself, which obviously does not have the database installed (it is in separate container, note that this is quite common error – for example: docker-compose refused connection to other container in same network).

    Change your connection string for example to something like:

    "ConnectionStrings": {
         "myDatabase" : "Server=database;Port=3306; Database=myDb; User=admin; Password=pass;"
    }
    

    Note that this is your compose file specific so it would be arguably better to specify this setting in the compose file itself via environment variables (since the higher precedence than JSON config files, note that : should be substituted with double underscore (__) – see the linked previously doc):

    server:
      #...
      environment:
        - ConnectionStrings__myDatabase=Server=database;Port=3306; Database=myDb; User=admin; Password=pass;
        - ASPNETCORE_ENVIRONMENT=Development
      #...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search