Как бороться с различиями в среде при развертывании основного приложения asp.net?

Есть ли способ изменить параметры среды при развертывании приложения ASP.NET Core (например, преобразования файла конфигурации с использованием сборки отладки / выпуска)?

Каков наилучший подход для поддержки нескольких параметров среды в приложениях .NET Core (что-то похожее на<appSettings file="local.config"> для местного, постановки и производства)?

Ответы на вопрос(2)

Используя дополнительныеappsettings.*.json файлы это хороший способ пойти. Фрагмент * можно использовать для смешивания в любом уникальном свойстве среды, которое различает машины, пользователей или сценарии развертывания.

Но вместо создания вашего объекта конфигурации с нуля, используяnew ConfigurationBuilder() (как показано во многих источниках в Интернете) Я рекомендую другой подход. Следующий код НЕ заменит существующий конфиг, но ДОБАВИТСЯ к нему:

    public IHostingEnvironment _environment { get; }
    public IConfiguration _configuration { get; }

    public Startup(IConfiguration configuration, IHostingEnvironment environment)
    {
        _environment = environment;

        // use the default config and add config from appsettings.COMPUTERNAME.json (if it exists)
        var builder = new ConfigurationBuilder()
            .SetBasePath(environment.ContentRootPath)
            .AddConfiguration(configuration)
            .AddJsonFile($"appsettings.{System.Environment.GetEnvironmentVariable("COMPUTERNAME")}.json", optional: true);
        _configuration = builder.Build();

    }

Фон:

Когда вы создаете свой проект на основедотнет новый шаблон, то ваш проект уже поставляется с полезной конфигурацией, которая автоматически создается черезCreateDefaultBuilder () метод. Эта конфигурация по умолчанию объединяет информацию из нескольких источников: appsettings.json, appsettings. {Environment} .json, Secret Manager, переменные среды и аргументы командной строки.

Если вы полностью перестроите конфигурацию самостоятельно, вы потеряете всю эту магию.

Подсказка:

В приведенном выше примереappsettings.COMPUTERNAME.json это только пример. Вы можете составить собственное имя файла JSON из любых данных в_environment или жеSystem.Environment это четко различает ваши различные сценарии разработки и развертывания.

Решение Вопроса

Центральный файл конфигурацииappsettings.json и вы можете иметь несколько файлов, какappsettings.Production.json и т.д., который будет загружен и переопределить настройки изappsettings.json.

Например

        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .SetBasePath(hostEnv.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();

Все, что вам нужно для этой работы, - это переменная среды для установки типа среды (см. ДокументациюВот).

Вы также можете иметь переменные окружения, которые переопределяют, если вы добавляетеAddEnvironmentVariables() вашему строителю конфигурации. Так что если у вас есть appsettings.json из

{
    "Data"  {
         "Default" {
              "ConnectionString" : "..."
         }
    }
}

и вы хотите переопределить это с помощью переменной среды, вы должны установить переменную среды с именем «Data: Default: ConnectionString», и ее значение переопределит параметры в appsettings.config и appsettings.Production.config (при условии, что ваш.AddEnvironmentalVariables() называетсяпосле .AddJsonFile() - Последняя регистрация с соответствующим ключом выигрывает) со значением из переменной среды.

Вы можете найти больше в официальной документацииВот.

Обновить

Поскольку в комментариях некоторые понимают это как единственный способ настройки среды, существует множество способов установить переменную среды (большинство из них описано вИспользуйте несколько сред в ASP.NET Core), все в конечном итоге сводится к тому, чтобы быть переменной среды, просто в другой области видимости:

Переменная среды (глобально, Windows cmd.exeset ASPNETCORE_ENVIRONMENT=Development или же$Env:ASPNETCORE_ENVIRONMENT = "Development" на PowerShell,export ASPNETCORE_ENVIRONMENT = Development на Linux)Переменная среды для каждой команды (т.е. linux:ASPNETCORE_ENVIRONMENT=Production dotnet MyApp.dll)

Контейнер Docker, т.е. через docker-compose.yaml

web:
    environment:
    - ASPNETCORE_ENVIRONMENT=Debugging
Docker контейнер через командную строкуdocker run -e ASPNETCORE_ENVIRONMENT=Debugging

в IIS через web.config.

<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" stdoutLogEnabled="true" >
  <environmentVariables>
    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
  </environmentVariables>
</aspNetCore>
На IIS установите его для AppPool (см.Вот)В Linux через файлы определения сервиса (см.документы)Служба приложений Azure через переменные среды, может быть установлена ​​для каждого слота и иметь разные слоты для Staging, Development, Production и, т. Е. Для развертывания в Staging, выполнения прогрева и замены с помощью Production.За исполнение черезdotnet run --launch-profile Development

Все они изменяют / устанавливают переменную среды в определенной области (глобально, локально для контейнера, внутри пула приложений, для каждого выполнения и т. Д.). Выберите тот, который соответствует вашим потребностям.

 Soma Yarlagadda20 июн. 2016 г., 08:21
Я прочитал это, но неправильно понял, что переменные env на самом деле хранятся в этом файле. Теперь это имеет смысл, спасибо за ваше время, разъясняющее концепцию.
 Soma Yarlagadda17 июн. 2016 г., 22:00
Спасибо. Где я могу найти документацию (ссылки на некоторые статьи или блоги) по этой теме?
 Serialize08 мая 2018 г., 21:34
@JoePhillips Меня беспокоило не то, существуют ли другие способы решения проблемы, а то, что мне показалось, что принятый ответ подразумевает, что применяется команда уровня операционной системы для включения поведения на уровне экземпляра приложения (если вы хотите использовать этот метод). Я не знал о области действия переменной.
 Soma Yarlagadda17 июн. 2016 г., 20:46
Это имеет смысл, но как бы вы переключались между средами при развертывании? Как динамически изменить значение hostEnv.EnvironmentName при развертывании в dev / staging / production? Спасибо.
 Soma Yarlagadda19 июн. 2016 г., 23:36
Может быть, я запутался, но, если переменные env читаются из переменных env Windows, почему они сохраняются в файле launchsettings.json как часть решения?
 Tseng08 мая 2018 г., 20:59
@Serialize: обновил вопрос, чтобы избежать дальнейшей путаницы, выберите тот, который соответствует вашим потребностям :)
 Joe Phillips08 мая 2018 г., 20:46
@Serialize В комментариях выше вы говорите, что вы можете передать в среду / профиль вместо установки env vars в системе. Просто прочитайте их.
 Serialize08 мая 2018 г., 20:37
@JoePhillips Вы думаете, что нет разницы между применением XML-преобразования к web.config и изменением переменных операционной системы целевых серверов, что может повлиять на любое количество других приложений в процессе ..? Возможно, я был защищен, но я никогда не ожидал бы изменить внутреннюю часть сервера публикации из приложения CI. Существует огромная разница между изменением конфигурации, которую когда-либо будет читать только IIS, в отличие от установки переменной уровня ОС, которая может повлиять на одноуровневые приложения. Я бы посоветовал ему работать любым методом, который не изменил хост в глобальном масштабе.
 Tseng17 июн. 2016 г., 22:34
Это команда Windows!technet.microsoft.com/en-us/library/...
 Tseng20 июн. 2016 г., 01:38
Прочитайте связанную статью, там заявлено !!!Этот файл содержит параметры, специфичные для каждого профиля, который Visual Studio настроен для запуска приложения, включая любые переменные среды, которые следует использовать. Он используется только в Visual Studio, когда вы нажимаете F5 для запуска / отладки приложения. Для производства вы используете реальные переменные среды
 Tseng27 апр. 2018 г., 01:42
@Serialize: где проблема? Вы можете установить переменную для каждого исполнения (по крайней мере, в Linux), вы можете поместить ее в Docker-контейнеры, которые изолированы от других приложений, вы можете установить переменную в IIS или globaly для всей машины и в Azure для каждого из слотов vm ( постановка, производство и т. д.) могут иметь свои собственные переменные и с 2.0 также сdotnet run --launch-profile Development, Не вижу проблемы здесь
 Soma Yarlagadda17 июн. 2016 г., 22:32
Как запустить несколько сред с использованием ASP.NET Core. В официальной документации нет упоминания о команде setx.
 Tseng17 июн. 2016 г., 21:37
Просто установите переменную. На окнахsetx Hosting:Environment Staging или жеexport Hosting__Environment=Staging (обратите внимание на двойное подчеркивание!) в Linux. Убедитесь, что у вас естьAddEnvironmentVariables() вызов при сборке конфига, иначе он не будет работать
 Serialize27 апр. 2018 г., 02:08
Проблема состоит в том, что рабочие процессы DevOps не включают в себя этап «изменение глобальной конфигурации хост-сервера» в порядке здравого смысла. Докер не вариант для всех. Цепочка инструментов CI ни в коем случае не должна отвечать за изменение среды хоста. Это ужасная идея для всех, кроме самых микроуправляемых сценариев использования.
 Tseng08 мая 2018 г., 20:46
@Serialize: посмотрите на мой комментарий выше, есть и другие варианты, которые немного отличаются в зависимости от того, где вы его развернули. Не существует единого определенного способа его настройки. Несколько способов сделать это в командной строке, т. Е. На Linux вы могли быASPNETCORE_ENVIRONMENT=Production dotnet MyApp.dll, Он установит переменную среды только для этой единственной команды, без глобальных настроек. Или вы можете настроить служебный файл (например, Ubuntu, см.docs.microsoft.com/en-us/aspnet/core/host-and-deploy/...). Есть десятки способов установить это
 Joe Phillips08 мая 2018 г., 21:38
@Serialize Это честно. Я на той же странице, что и вы - я думаю, что использование переменных env было странным решением, но оно дает большую гибкость, если вы знаете об альтернативных способах его использования.
 Serialize27 апр. 2018 г., 01:34
Это не может быть реальным решением, конечно. Если так, то это самая хрупкая вещь, о которой я когда-либо слышал. Операционная система сервера должна заявить о себе как об особом использовании. В самом деле? Если это так, ядро ​​ASP.NET может спрыгнуть с обрыва.
 stt10614 окт. 2017 г., 11:23
Как переключить среду при развертывании на Azure?
 Tseng17 июн. 2016 г., 22:02
Установка переменных в Windows или как конфигурация ASP.NET Core получает свои значения? Я связал две статьи в своем посте, одну о конфигурации и одну о том, как запустить ASP.NET Core в нескольких средах.
 Joe Phillips07 мая 2018 г., 16:03
@Serialize Так как бы вы предложили это работает? В прошлом CI обрабатывал это, выбирая правильное преобразование конфигурации. Это действительно ничем не отличается, кроме как это делает.
 Serialize08 мая 2018 г., 21:24
@ Tseng Спасибо. После прочтения всего связанного здесь, это было так: «Переменные среды могут быть определены дляпроцесс в атрибуте processPath. Укажите переменную среды с дочерним элементом environmentVariable элемента коллекции environmentVariables. Переменные среды, установленные в этом разделе, имеют приоритет над системными переменными среды. "ссылка на сайт это помогло мне понять. Возможно, другие тоже сочтут это полезным.
 Tseng14 окт. 2017 г., 11:31
@ stt106: нет. Среда читается при запуске приложения, поэтому вы просто изменяете переменную среды в своем веб-приложении или виртуальной машине Azure (где бы вы ни развертывали его) до или после его развертывания (если приложение уже запущено, требуется перезапуск приложения). Как правило, в веб-приложениях Azure используются несколько слотов: один с переменной среды производства, другой как «Разработка» или «Подготовка». Вы развертываете в неактивном слоте и тестируете, затем переключаете слоты с помощью powershell или портала Azure.docs.microsoft.com/en-us/azure/app-service/...

Ваш ответ на вопрос