How to set config file in .Net Core Console app for multiple IDEs when running Docker container

Our team developed a message processing service from Kafka. It was a .Net Core console application that subscribed to topics, and when a message appeared in each of them, it performed a certain processing algorithm. At the first iterations of the development of our service, the deployment was quite simple: we published applications, transferred the ready-made build files to the server, created a docker image and launched the service in a container. We lived like this until load testing came to us and deployed in a neighboring circuit. The appsettings.json configuration file in these contours, of course, was different and we had one more step in our deployment - fixing the configuration file with handles. At this stage, the human factor intervened, and sometimes we forgot to edit the file, which led to errors and wasted time.When we got tired of it (very quickly), we decided to call DevOps to help. But still, it took time, and there was no more effort to edit the config by hand. Then I came up with and implemented a fairly quick solution, which I want to talk about in this article.



Here are our initial conditions:



  1. Our service is Console Application, and unlike ASP.NET Core Web Application, we didn't have a solution out of the box.
  2. The application is launched from the docker container.


Well, let's see how to use multi configuration in a console application. First, let's create configuration files for our Dev and Testing environments:





There is no default nesting in console applications. Therefore, open the .csproj project file and add:



<ItemGroup>
	<Content Include="appsettings.json">
		<CopyToOutputDirectory>Always</CopyToOutputDirectory>
	</Content>
	<Content Include="appsettings.Dev.json;appsettings.Testing.json;">
		<DependentUpon>appsettings.json</DependentUpon>
		<CopyToOutputDirectory>Always</CopyToOutputDirectory>
	</Content>
</ItemGroup>

      
      





Attached files with the name of the development environment appeared in the appsettings.json file:







In the appsettings.Dev.json and appsettings.Testing.json files, add those parts of the config that change depending on the environment. Let's change the name of the Kafka topics in the load testing loop by adding the necessary parameters to appsettings.Testing.json:



{
  "Kafka": 
  {
    "EventMainTopicTitle": "Test_EventMain",
    "EventDelayTopicTitle": "Test_EventDelay",
    "EventRejectTopicTitle": "Test_EventReject"
  }
}

      
      





It remains only to select the desired appsettings.json file during the start of the service. To do this, let's make changes to the Program class:



///  
private static IServiceProvider ConfigureServices()
{
    //    
    const string environmentVariableName = "ASPNETCORE_ENVIRONMENT";
    //    
    var environmentName = 
        Environment.GetEnvironmentVariable(environmentVariableName);

    var services = new ServiceCollection();

    _configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
        .AddJsonFile("appsettings.json")
        //  json-   environmentName
        .AddJsonFile($"appsettings.{environmentName}.json")
        .AddEnvironmentVariables()
        .Build();

    services.AddSingleton(_configuration);
    services.AddSingleton<KafkaHandler>();

    return services.BuildServiceProvider();
}

      
      





Now everything is ready to start the service in a docker container.



It remains to specify the environment variables for the container. There are several ways to do this:



  • command line
  • text file
  • docker compose


I stopped at specifying variables on the command line. Here's an example script to create an image and run a container:



# Build image
# docker build . -t consoleapp

# Run container on Dev
# docker run -d <i>--env ASPNETCORE_ENVIRONMENT=Dev</i> --name app consoleapp

      
      





There are more elegant solutions for creating a pipeline for your deployment, but this method can be implemented in a short time, which is very critical at the initial stage of project creation.



Link to GitHub with the project .



Thanks for your attention and pleasant coding!



All Articles