actions / runner

The Runner for GitHub Actions :rocket:
https://github.com/features/actions
MIT License
4.65k stars 895 forks source link

C# application in Docker Container cannot read Environment Variables #3270

Closed erikrose100 closed 2 months ago

erikrose100 commented 2 months ago

Describe the bug I have created an ASP.NET application that I am able to run locally, both containerized and natively. I am using the Environment.GetEnvironmentVariable() method to retrieve environment variables during DI setup. Locally I am able to get this to work by setting the env vars in my shell or passing them in using the -e option with docker run.

I have a CI workflow I am trying to create where the last step uses docker run to check that the container will run. I have set it up to grab the env variables from repo secrets. When the workflow hits that step, I get the following error:

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')

Relevant section of code:

// Get connection string from Environment variables
string? connectionString = Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CONNECTION_STRING");
double configCacheExpiration = Convert.ToDouble(Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CACHE_EXPIRATION"));

workflow step:

 run: |
    docker run --rm ${{ env.TEST_TAG }} -e METADATA_API_CONFIG_CACHE_EXPIRATION=1 -e METADATA_API_CONFIG_CONNECTION_STRING="${{ env.METADATA_API_CONFIG_CONNECTION_STRING }}" -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ --stop-timeout 30

I have tried passing in the environment variable both in the env: for the workflow, envs for the script step, and by adding the -e options in the shell step. I have tried both bash and pwsh. None of these have worked.

The secrets are not null and can be shown to have a value when referenced in bash directly. Seems somehow the dotnet environment in the container is not able to reach the environment vars of the host runner.

To Reproduce Steps to reproduce the behavior:

  1. Create a containerized dotnet 8.0 ASP.NET app that references env vars in DI setup (example)
  2. Create an actions workflow that attempts to run the container after its built, passing in the env vars inline (example)
  3. See above error

Expected behavior Container should run successfully as it does locally using the same options.

Runner Version and Platform

ubuntu-latest

Job Log Output

Run docker run --rm user/app:test -e METADATA_API_CONFIG_CACHE_EXPIRATION=1 -e METADATA_API_CONFIG_CONNECTION_STRING="***" -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ --stop-timeout 30
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationOptions.Connect(String connectionString)
   at Program.<>c__DisplayClass0_0.<<Main>$>b__1(AzureAppConfigurationOptions options) in /App/Program.cs:line 22
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationSource.<>c__DisplayClass2_0.<.ctor>b__0()
   at Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationSource.Build(IConfigurationBuilder builder)
   at Microsoft.Extensions.Configuration.ConfigurationManager.AddSource(IConfigurationSource source)
   at Microsoft.Extensions.Configuration.ConfigurationManager.Microsoft.Extensions.Configuration.IConfigurationBuilder.Add(IConfigurationSource source)
   at Microsoft.Extensions.Configuration.AzureAppConfigurationExtensions.AddAzureAppConfiguration(IConfigurationBuilder configurationBuilder, Action`1 action, Boolean optional)
   at Program.<Main>$(String[] args) in /App/Program.cs:line 20
Error: Process completed with exit code 1.
bduffany commented 2 months ago

Is ${{ env.TEST_TAG }} the name of the docker image top be run? This needs to come after all of the other options in the docker command. i.e. it needs to go at the very end

So change

docker run --rm ${{ env.TEST_TAG }} -e METADATA_API_CONFIG_CACHE_EXPIRATION=1 -e METADATA_API_CONFIG_CONNECTION_STRING="${{ env.METADATA_API_CONFIG_CONNECTION_STRING }}" -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ --stop-timeout 30

to

docker run --rm -e METADATA_API_CONFIG_CACHE_EXPIRATION=1 -e METADATA_API_CONFIG_CONNECTION_STRING="${{ env.METADATA_API_CONFIG_CONNECTION_STRING }}" -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ --stop-timeout 30 ${{ env.TEST_TAG }}

erikrose100 commented 2 months ago

@bduffany that was it, thank you so much! somehow missed that