#docker #.net-core #console-application
#docker #.net-core #консольное приложение
Вопрос:
Я пытаюсь определить среду, чтобы знать, из какого файла appsettings.json читать.
У меня есть приведенный ниже код, который, судя по поиску в Google, является общепринятым способом достижения этого (я более чем рад рассмотреть другие способы сделать это, если есть способы получше ???):
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", EnvironmentVariableTarget.Machine);
Console.WriteLine($"Environment: {environmentName}");
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{environmentName}.json", false, true)
.AddEnvironmentVariables();
_configuration = builder.Build();
Вышеуказанное отлично работает при локальном запуске, получая значение из системных переменных:
Однако, если я запускаю приложение в контейнере docker, environmentName
оно пустое.
Как мне установить переменные среды в docker?
Я перепробовал несколько способов достижения этого, но ни один из них не дал желаемого эффекта:
В моем dockerfile у меня было:
ENTRYPOINT ["dotnet", "out/myapp.dll","--environment=test"]
Я также пытался передать его в качестве параметра при запуске контейнера:
docker run -e ASPNETCORE_ENVIRONMENT=test --rm dotnetapp-dev
В моем последнем примере выше я заметил, что я мог бы получить параметр, вызвав этот код ПОСЛЕ того, как я создал конфигурацию, но там уже слишком поздно — мне это нужно перед вызовом Build()
:
_configuration = builder.Build();
Console.WriteLine(_configuration["ASPNETCORE_ENVIRONMENT"]);//this works
Кому-нибудь удалось установить системные переменные в контейнере docker?
Комментарии:
1. В вашем файле docker добавьте
ENV ASPNETCORE_ENVIRONMENT="Production"
. Вы также можете определить значение по умолчанию в своем файле cs. Как это делает aspnetcore.2. Это была еще одна из моих попыток, но, похоже, это тоже не сработало.
3. Вы пытались удалить
EnvironmentVariableTarget.Machine
параметры?4. По крайней мере, вы можете создать свой объект конфигурации в два этапа. Но это некрасиво
5. Как вы можете видеть здесь и здесь , EnvironmentVariableTarget поддерживает только пользователя и компьютер в Windows. Вот почему все ваши предыдущие тесты не работали
Ответ №1:
Благодаря @Kalten мне удалось получить решение, которое работает — это кажется действительно простым при просмотре кода, но было немного сложно добраться:
const string environmentVariableName = "ASPNETCORE_ENVIRONMENT";
var environmentName = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine);
if (string.IsNullOrEmpty(environmentName))
{
//this is required for docker
environmentName = Environment.GetEnvironmentVariable(environmentVariableName);
}
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{environmentName}.json", false, true)
.AddEnvironmentVariables();
_configuration = builder.Build();
Эта строка — единственный способ получить системные переменные при локальном запуске, но это не работает для docker:
var environmentName = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine);
Эта строка — единственный способ получить системные переменные при запуске в docker, но это не работает локально:
var environmentName = Environment.GetEnvironmentVariable(environmentVariableName);
Мне пришлось получить, environmentName
используя оба метода с проверкой на null после первого. Не идеально, но это работает, и мне не придется переименовывать файлы appsettings.json, что было одним из моих вариантов, когда я, похоже, ничего не мог получить от docker.
Итак, в docker я могу передать переменную в качестве аргумента: docker run -e ASPNETCORE_ENVIRONMENT=Staging --rm dotnetapp-dev
или я могу поместить переменную в dockerfile:
FROM microsoft/dotnet:2.1-sdk
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Regression
//other stuff here