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.
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.appsettings.json
– still not sure about this one, if it get call or not?appsettings.Development.json
– This is what mycompose.yaml
called. I assume that when I defineASPNETCORE_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
Your database server runs on the host named
database
as you define in the environment variableDBHOST
, but in you connection string you try to connect tolocalhost
. Change you ConnectionString and it should workJust to elaborate on the config first:
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:
i.e. all configuration sources are added hierarchically (based on the environment), so this:
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 fromappsettings.Devlopment.json
will be used.As for your specific issue, in the following:
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:
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):