未在Dockerfile中设置环境变量

时间:2020-02-28 13:30:06

标签: docker docker-compose dockerfile

我有一个项目,其中包含2个Dockerfile,一个用于后端,一个用于数据库。 dockerfile位于单独的文件夹中。我使用如下所示的docker-compose.yml文件构建了两个图像:

version: "3.7"
services:
  dotnet-backend:
    container_name: dotnet-backend
    build: .
    env_file: .env
    links:
      - mssql-db
    ports:
      - "8000:80"
  mssql-db:
    container_name: mssql-db
    build: ./Database
    env_file: .env
    volumes:
     - ./Database/:/scripts/
    ports:
      - "1433:1433"
    expose:
      - "1433"
    command:
      - /bin/bash
      - -c 
      - |
        /opt/mssql/bin/sqlservr &
        sleep infinity

如您所见,我使用.env文件作为环境变量,该文件位于src文件夹中,与后端和其余后端代码的Dockerfile相同。

这是我的后端Dockerfile:

FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Debug -o out MyProject.csproj

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY --from=build-env /app/out .

EXPOSE 80

ENV ASPNETCORE_ENVIRONMENT=$ASPNETCORE_ENVIRONMENT

ENTRYPOINT ["dotnet", "MyProject.dll"]

这是我的数据库Dockerfile(位于./Database中):

FROM mcr.microsoft.com/mssql/server:2017-latest

ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=$SA_PASSWORD
ENV MSSQL_PID=Developer
ENV MSSQL_TCP_PORT=1433 

WORKDIR /src
COPY ./ /scripts/

EXPOSE 1433 

RUN (/opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started" && sleep 5s && (for foo in /scripts/*.sql;do /opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -P$SA_PASSWORD  -i$foo;done)

最后是我的.env文件:

SA_PASSWORD=SomePassword
ASPNETCORE_ENVIRONMENT=Development
ConnectionStrings__My_db=Data Source=tcp:mssql-db,1433;Initial Catalog=DevDB;User ID=sa;Password=SomePassword

奇怪的是,设置了ASPNETCORE_ENVIRONMENT变量,正如我通过测试我的API可以知道它正在开发模式下运行一样,而且.env文件中的连接字符串也得到了设置,因为我的API可以在以下情况下连接到我的数据库我手动输入密码。但是未设置SA_PASSWORD环境变量。这是docker-compose up --build命令的输出:

enter image description here

那么为什么要设置其他变量和连接字符串而不设置密码?如果我在数据库Dockerfile中将ENV SA_PASSWORD=$SA_PASSWORD替换为ENV SA_PASSWORD=SomePassword,一切都会正常工作。

2 个答案:

答案 0 :(得分:1)

您根本不需要在docker映像中设置环境变量,并且可以使用以下更改来解决问题

ASPNETCORE_ENVIRONMENT 之所以有效,是因为该应用仅在运行时而不是在构建时进行检查

数据库docker文件

FROM mcr.microsoft.com/mssql/server:2017-latest

ENV ACCEPT_EULA=Y
ENV MSSQL_PID=Developer
ENV MSSQL_TCP_PORT=1433

WORKDIR /src
COPY ./ /scripts/

EXPOSE 1433 

COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

docker-entrypoint.sh(chmod a + x)

#!/bin/bash -e


(/opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started" && sleep 5s && (for foo in /scripts/*.sql;do /opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -P$SA_PASSWORD  -i$foo;done)

exec "$@"

exit 0

应用docker文件

FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Debug -o out MyProject.csproj

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY --from=build-env /app/out .

EXPOSE 80

ENTRYPOINT ["dotnet", "MyProject.dll"]

您也可以将这些文件移到环境文件中,建议为容器分开环境文件

ENV ACCEPT_EULA=Y
ENV MSSQL_PID=Developer
ENV MSSQL_TCP_PORT=1433

答案 1 :(得分:0)

这不是从环境中获取var的有效方法。

Dockerfile中的变量$ SA_PASSWORD实际上是Dockerfile范围和构建映像时间的变量。

var没有值,因为通过ARG命令(https://docs.docker.com/engine/reference/builder/#arg)进行分配的方式。

无论如何,如果您需要声明SA_PASSWORD并在容器运行时读取环境信息,则必须通过ENTRYPOINT来执行此操作。容器启动时执行ENTRYPOINT。