首页 > 解决方案 > NLog config 设置来自 docker run 参数的连接字符串

问题描述

我有一个需要在 Docker 容器中运行的 .NET Core api 项目。该项目使用 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>
...

这是我的 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"]
ARG log_connection
ENV logs_connection_string=$log_connection

这些是我在运行时传递连接字符串的一些尝试:

我没有太多使用 Docker 的经验,所以这种方法甚至可能不可行。我愿意接受任何建议。

标签: dockerasp.net-corenlog

解决方案


既不是ARG也不ENV是为了你想要完成的事情。

您需要的是某种入口点脚本,它将读取您在运行命令(log_connectionlog_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`"] 

或者,您可以在 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.


推荐阅读