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"]
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With