如何在从 docker-compose 调用的 .sh 文件中使用 .NET Core 机密

How to use .NET Core secrets in .sh file that is called from docker-compose

背景

我正在编写一个 .NET 5 应用程序并使用 .net 用户机密作为我的密钥(数据库连接和密码)。

最近我决定学习 Dockers 并更新我的应用程序以使用它,以便使用 Visual Studio 为我的 API 项目生成一个 docker 文件,然后创建了一个 docker-compose 文件,其中包含 API 项目和数据库(以及一些与此问题无关的内容)。

几乎一切正常。从技术上讲,我可以对这些秘密进行硬编码,然后应用程序就可以正常运行了。

我有一些秘密,其中大部分工作正常,例如:数据库连接秘密工作良好,在 C# 代码中,我执行以下代码并从 .net user-secrets 获取值:

config.GetConnectionString("Default");

代码详情

我有一个密钥,其中包含 sa 用户的 SQL 密码。

dotnet user-secrets set "SA_PASSWORD" "<MySecretPassword>"

然后我有 docker-compose 文件,它属于 Linux 系统,这是代码的一部分:

sql_in_dc:
  build:
    context: .
    dockerfile: items/sql/sql.Dockerfile
  restart: always
  ports:
    - "1440:1433"
  environment:
    - ACCEPT_EULA=Y
    - SA_PASSWORD=$SA_PASSWORD
    - ASPNETCORE_ENVIRONMENT=Development
    - USER_SECRETS_ID=80a155b1-fb7a-44de-8788-4f5759c60ff6
  volumes:
    - $APPDATA/Microsoft/UserSecrets/$USER_SECRETS_ID:/root/.microsoft/usersecrets/$USER_SECRETS_ID
    - $HOME/.microsoft/usersecrets/$USER_SECRETS_ID:/root/.microsoft/usersecrets/$USER_SECRETS_ID

如您所见,它调用了 sql.Dockerfile,即:

FROM mcr.microsoft.com/mssql/server 

ARG PROJECT_DIR=/tmp/devdatabase
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR
COPY items/sql/InitializeDatabase.sql ./
COPY items/sql/wait-for-it.sh ./
COPY items/sql/entrypoint.sh ./
COPY items/sql/setup.sh ./

CMD ["/bin/bash", "entrypoint.sh"]

那么setup.sh就是:

# Wait for SQL Server to be started and then run the sql script
./wait-for-it.sh sql_in_dc:1433 --timeout=0 --strict -- sleep 5s && \
/opt/mssql-tools/bin/sqlcmd -S localhost -i InitializeDatabase.sql -U sa -P "$SA_PASSWORD"

问题

文件 setup.sh 无法识别来自机密文件的 $SA_PASSWORD 环境变量。

如果我将 docker-compose.yml 文件更改为:

,效果很好
- SA_PASSWORD=SomePassword

备注

非常感谢!

docker-compose.yml 在您的 主机 OS 上执行(因此它可以使用 OS 环境变量或 .env 文件中的变量,或来自撰写文件,...)。 运行 图像 - 容器有它自己的一组环境变量 ,在你的情况下,这意味着 运行 容器没有 SA_PASSWORD 变量。 如果您在主机 OS.

上设置了 SA_PASSWORD 变量,那么您的用例将起作用

您可以检查容器中设置了哪些变量(如果您的图像带有 bash):

docker exec -it [container id] bash
printenv 

dotnet-secrets 环境变量是在 execution/runtime 期间从 Visual Studio 隐式创建的(请参阅项目文件中的条目)。

正如您提到的 “撰写文件无法识别 dotnet-secrets”

您可以使用:

  1. *.env File
  2. 将其传递给组合命令:with -e
  3. compose yml 中的纯文本:- SA_PASSWORD=thepassword
  4. 作为主机OS变量

请记住,Visual Studio 在 运行 或调试您的 docker 容器时会增加一些魔力。 See Visual Studio container volume mapping: For ASP.NET core web apps, there might be two additional folders for the SSL certificate and the user secrets, which is explained in more detail in the next section.