NLog 配置从 docker 运行 参数设置连接字符串
NLog config set connection string from docker run argument
我有一个 .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 运行 -e log_connection="connection_string" -itd -p 1234:80 --name service service
- docker 运行 -e log_connection_string="connection_string" -itd -p 1234:80 --name service service
我没有太多的使用经验Docker,所以这种方法甚至可能行不通。我愿意接受任何建议。
ARG
和 ENV
都不是您想要完成的。
您需要的是某种入口点脚本,它将读取您在 运行 命令中设置的环境变量(在您的示例中为 log_connection
或 log_connection_string
),做出反应错误或将其设置为默认值(如果未设置),最后编辑 nlog.config
并将 <connectionString>
的值设置为变量的值,最后 运行s 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`"]
或者,您可以在 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
.
@Konrad Botor 的回答是可行的,因为他提供了一个非常好的答案,但对于我的用例,有一种更简单的方法。
@RolfKristensen 的评论为我指明了正确的方向。
ASP.NET 核心应用程序默认加载环境的变量(请参阅 SO 上的此答案:Using AddEnvironmentVariables in .net core 3.1 app)。 运行上传图像时传递的环境变量,可以在应用程序中使用以下方式访问:
Environment.GetEnvironmentVariable("env_name")
.
如@RolfKristensen 所述,NLog 知道如何加载环境变量。 nlog.config 文件中的连接字符串标记如下所示:
<connectionString>${environment:CONNECTION_STRING}</connectionString>
运行 命令如下所示。
docker run -itd -p 1234:80 --name test -e CONNECTION_STRING="..." app
将从 运行 处传递的变量正确加载连接字符串。
为了传递敏感数据,这种方法存在安全风险,因为 docker 运行 命令将保留在命令历史记录中。但是有人可以使用 composer 文件或将主机的环境变量传递给 运行 命令来降低风险。
编辑
我使用Visual Studio生成的Dockerfile。
#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"]
我有一个 .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 运行 -e log_connection="connection_string" -itd -p 1234:80 --name service service
- docker 运行 -e log_connection_string="connection_string" -itd -p 1234:80 --name service service
我没有太多的使用经验Docker,所以这种方法甚至可能行不通。我愿意接受任何建议。
ARG
和 ENV
都不是您想要完成的。
您需要的是某种入口点脚本,它将读取您在 运行 命令中设置的环境变量(在您的示例中为 log_connection
或 log_connection_string
),做出反应错误或将其设置为默认值(如果未设置),最后编辑 nlog.config
并将 <connectionString>
的值设置为变量的值,最后 运行s 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`"]
或者,您可以在 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
.
@Konrad Botor 的回答是可行的,因为他提供了一个非常好的答案,但对于我的用例,有一种更简单的方法。 @RolfKristensen 的评论为我指明了正确的方向。
ASP.NET 核心应用程序默认加载环境的变量(请参阅 SO 上的此答案:Using AddEnvironmentVariables in .net core 3.1 app)。 运行上传图像时传递的环境变量,可以在应用程序中使用以下方式访问:
Environment.GetEnvironmentVariable("env_name")
.
如@RolfKristensen 所述,NLog 知道如何加载环境变量。 nlog.config 文件中的连接字符串标记如下所示:
<connectionString>${environment:CONNECTION_STRING}</connectionString>
运行 命令如下所示。
docker run -itd -p 1234:80 --name test -e CONNECTION_STRING="..." app
将从 运行 处传递的变量正确加载连接字符串。
为了传递敏感数据,这种方法存在安全风险,因为 docker 运行 命令将保留在命令历史记录中。但是有人可以使用 composer 文件或将主机的环境变量传递给 运行 命令来降低风险。
编辑
我使用Visual Studio生成的Dockerfile。
#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"]