NLog config устанавливает строку подключения из docker аргумент запуска - PullRequest
0 голосов
/ 03 августа 2020

У меня есть проект. NET Core api, который нужно запускать в контейнере Docker. Проект использует NLog для записи данных в базу данных. Я хочу установить свойство строки подключения в файле nlog.config при запуске контейнера.

Приложение будет развернуто на разных клиентах и ​​будет использовать их базы данных для ведения журнала.

Вот как Я попытался настроить строку подключения в файле nlog.config:

...
  <target name="database" xsi:type="Database">
      <connectionString>'${environment:logs_connection_string}'</connectionString>
      <dbProvider>MySql.Data.MySqlClient.MySqlConnection, MySql.Data</dbProvider>
...

Это мой файл Docker:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Service/Service.csproj", "Service/"]
COPY ["Extensions/CustomExtensions.csproj", "Extensions/"]
RUN dotnet restore "Service/Service.csproj"
COPY . .
WORKDIR "/src/Service"
RUN dotnet build "Service.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Service.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Service.dll"]
ARG log_connection
ENV logs_connection_string=$log_connection

Это некоторые из моих действий по передаче строки подключения при запуске :

  • docker run -e log_connection = "connection_string" -itd -p 1234: 80 --name service service
  • docker run -e log_connection_string = "connection_string" -itd -p 1234: 80 --name service service

У меня нет большого опыта использования Docker, поэтому этот подход может быть даже неприменим. Я открыт для любых предложений.

Ответы [ 2 ]

1 голос
/ 05 августа 2020

@ Ответ Конрада Ботора выполним, поскольку он доказал очень хороший ответ, но для моего варианта использования есть более простой способ. Комментарий @ RolfKristensen указал мне правильное направление.

An ASP. NET Базовое приложение загружает переменные среды по умолчанию (см. Этот ответ на SO: Использование AddEnvironmentVariables в. net core 3.1 приложение ). Переменные среды, передаваемые при запуске изображения, могут быть доступны в приложении с помощью:

Environment.GetEnvironmentVariable("env_name").

Как упоминал @ RolfKristensen, NLog знает, как загружать переменные среды. Тег строки подключения в файле nlog.config выглядит так:

<connectionString>${environment:CONNECTION_STRING}</connectionString>

Команда запуска выглядит так.

docker run -itd -p 1234:80 --name essilor -e CONNECTION_STRING="..." app

Строка подключения будет загружена правильно из переменной, переданной при запуске.

Для передачи конфиденциальных данных этот подход представляет собой угрозу безопасности, поскольку команда docker run останется в истории команд. Но кто-то может использовать файл composer или передать переменные среды хоста в команду запуска, чтобы уменьшить риск.

EDIT

Я использую Dockerfile, созданный Visual Студия.

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Service/Service.csproj", "Service/"]
COPY ["Extensions/CustomExtensions.csproj", "Extensions/"]
RUN dotnet restore "Service/Service.csproj"
COPY . .
WORKDIR "/src/Service"
RUN dotnet build "Service.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Service.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Service.dll"]
1 голос
/ 03 августа 2020

Ни ARG, ни ENV не предназначены для того, что вы хотите выполнить. sh.

Вам нужен какой-то сценарий точки входа, который будет читать переменную среды, которую вы устанавливаете при запуске (в ваших примерах - log_connection или log_connection_string), реагирует ошибкой или устанавливает значение по умолчанию, если оно не задано, и, наконец, редактирует nlog.config и устанавливает значение <connectionString> для значения переменной и наконец запускается dotnet Service.dll.

Например, вы можете установить свое соединение в nlog.config следующим образом:

<connectionString>log_connection_string</connectionString>

Затем создайте файл run.ps1 со следующим содержимым:

#!/opt/microsoft/powershell/7/pwsh
if (-not (Test-Path env:log_connection_string)) { $env:log_connection_string = 'default value for log_connection_string' }
((Get-Content -Path path\to\nlog.config -Raw) -replace 'log_connection_string',$Env:log_connection_string) | Set-Content -Path path\to\nlog.config
dotnet Service.dll

скопируйте его в каталог /app во время сборки образа

и замените последние три строки вашего Dockerfile на:

ENTRYPOINT ["./run.ps1"]

Изменить: чтобы установить Powershell Core в свой базовый образ, используйте следующую команду в Dockerfile (лучше всего под FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base):

RUN curl https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb --output packages-microsoft-prod.deb --silent && \
dpkg -i packages-microsoft-prod.deb && \
rm packages-microsoft-prod.deb && \
apt-get update && \
apt-get install -y powershell && \
apt-get clean

Вам также необходимо либо сделать run.ps1 исполняемым файлом, либо изменить точку входа на:

ENTRYPOINT ["/opt/microsoft/powershell/7/pwsh", "-Command","./run.ps1`enter code here`"] 

В качестве альтернативы вы можете использовать эквивалент nt в Bash (назовем его run.sh):

#!/bin/bash
[[ -z "$log_connection_string" ]] && export log_connection_string="default value for log_connection_string"
sed -i 's/log_connection_string/'"$log_connection_string"'/' path\to\nlog.config
dotnet Service.dll

И точка входа должна быть установлена ​​на:

ENTRYPOINT ["/bin/bash", "-c", "./run.sh"]

Заключительное примечание: нет закона, который препятствует одному от использования строчных имен для переменных окружения, но общепринято соглашаться писать заглавными буквами, например. LOG_CONNECTION_STRING вместо log_connection_string.

...