Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use .env file for docker-compose vars in config for asp.net core app?

I am trying to use a .env file to specify a base connection string for my containers in docker compose. When I run docker-compose config everything looks good, however when I run my app the connection string is not including the variable from the .env file.

This is a sample of my .env:

BASE_CONNECTION_STRING=Server=sqldb;userid=root;pwd=Pass@word;

and here is a sample of my docker-compose:

  listings.api:
    environment:
      ASPNETCORE_ENVIRONMENT: Development
      ASPNETCORE_URLS: http://+:80
      ConnectionString: ${BASE_CONNECTION_STRING}Database=RentalListings.Services.ListingsDb;

When I run docker-compose config I get the correct result, namely:

ConnectionString: Server=sqldb;userid=root;pwd=Pass@word;Database=RentalListings.Services.ListingsDb;

However, when I run my app I don't get the correct value. Running configuration["ConnectionString"] returns just Database=RentalListings.Services.ListingsDb;

I tried adding .AddEnvironmentVariables(); to my ConfigurationBuilder() which did add environment variables that were not there before when I inspected by configuration before, but did not add the ones from the .env file. Regardless I'm not sure if this part should matter as I would assume that this variable should be compiled and passed in by docker regardless of my ConfigurationBuilder.

Any help would be greatly appreciated :)

UPDATE: The call to configuration["ConnectionString"] is in my ConfigureServices() in Startup.cs:

public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddCustomMVC(Configuration)
                .AddCustomDbContext(Configuration, _loggerFactory)
                .AddAppSettings(Configuration);
        }

with:

public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration, ILoggerFactory loggerFactory)
        {
            ILogger<Startup> logger = loggerFactory.CreateLogger<Startup>();
            logger.LogInformation($"Conn string: {configuration["ConnectionString"]}");
            services.AddDbContext<ListingsContext>(options =>
            {
                options.UseMySql(configuration["ConnectionString"]);
                options.UseLoggerFactory(loggerFactory);
            });

            return services;
        }

Here is my full docker-compose.yml:

version: '3.4'

services:
  sqldb:
    image: mariadb:latest

  listings.api:
    image: ${REGISTRY:-listings}/listings.api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Listings/Listings.API/Dockerfile
    depends_on:
      - sqldb

  identity.api:
    image: ${REGISTRY:-identity}/identity.api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Identity/Identity.API/Dockerfile
    depends_on:
      - sqldb

  webmvc:
    image: ${DOCKER:-listings}/webmvc:${TAG:-latest}
    build:
      context: .
      dockerfile: src/WebApps/WebMVC/Dockerfile
    depends_on:
      - listings.api

Here is my docker-compose.override.yml:

version: '3.4'

services:

  sqldb:
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"

  listings.api:
    environment:
      ASPNETCORE_ENVIRONMENT: Development
      ASPNETCORE_URLS: http://+:80
      ConnectionString: ${BASE_CONNECTION_STRING}Database=RentalListings.Services.ListingsDb;
    ports:
      - "57931:80"

  identity.api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - ConnectionString=${BASE_CONNECTION_STRING}Database=RentalListings.Services.IdentityDb;
    ports:
      - "57932:80"

  webmvc:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:80
      - ListingsAPIUrl=http://listings.api:80/api/v1
      - HomeUrl=http://localhost:55338
      - ListingsScope=${OIDC_SCOPES_LISTINGS}
      - ClientId=${OIDC_MVC_CLIENT_ID}
      - ClientSecret=${OIDC_MVC_CLIENT_SECRET}
    ports:
      - "55338:80"

And here is the Dockerfile for the Listings.API

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY src/Services/Listings/Listings.API/Listings.API.csproj src/Services/Listings/Listings.API/
RUN dotnet restore src/Services/Listings/Listings.API/Listings.API.csproj
COPY . .
WORKDIR /src/src/Services/Listings/Listings.API
RUN dotnet build Listings.API.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish Listings.API.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Listings.API.dll"]
like image 312
Robin Lashof-Regas Avatar asked Oct 20 '25 22:10

Robin Lashof-Regas


1 Answers

If you're debugging through Visual Studio (where docker-compose is the startup project), by default VS does not load the .env file. There is an issue that was closed where the recommendation was to create a docker-compose.override.yml that contains a reference to the env_file

 env_file:
    - .env

This will work. However in my case, I did not want to add the .env file reference to the docker-compose.override.yml so I created a new file: docker-compose-debug.yml and I modified the docker-compose.dcproj by adding the AdditionalComposeFilePaths node. My docker-compose.dcproj now looks like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk" DefaultTargets="Build">
  <PropertyGroup Label="Globals">
    <ProjectVersion>2.1</ProjectVersion>
    <DockerTargetOS>Linux</DockerTargetOS>
    <ProjectGuid>a7290ad5-4ae3-4f88-9113-eed88eae9a32</ProjectGuid>
    <DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
    <DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>
    <DockerServiceName>demo.api</DockerServiceName>
    <Configurations>Debug;Release</Configurations>
    <Platforms>AnyCPU</Platforms>
    <AdditionalComposeFilePaths>docker-compose-debug.yml</AdditionalComposeFilePaths>
  </PropertyGroup>
  <ItemGroup>
    <None Include="docker-compose.override.yml">
      <DependentUpon>docker-compose.yml</DependentUpon>
    </None>
    <None Include="docker-compose.yml" />
    <None Include=".dockerignore" />
  </ItemGroup>
</Project>
like image 117
Alberto Guerrero Avatar answered Oct 24 '25 06:10

Alberto Guerrero



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!