Docker-compose无法设置环境变量。

22
当我运行docker-compose build && docker-compose up redis命令时,使用了docker-compose.yaml文件中指定的environment参数和在Dockerfile中指定的RUN env,但我设置的环境变量没有被打印出来。为什么会这样呢?我使用的是docker-compose 1.4.2版本。以下是相关文件:docker-compose.yaml文件中environment参数作为KEY=value对列表:
redis:
    build: ../storage/redis
    ports:
      - "6379:6379"
    environment:
      - FOO='bar'

docker-compose.yaml 中使用 environment 字典:

redis:
    build: ../storage/redis
    ports:
      - "6379:6379"
    environment:
      - FOO: 'bar'

Dockerfile

FROM redis:2.6
MAINTAINER me@email.com

RUN mkdir -p /var/redis && chown -R redis:redis /var/redis

RUN echo '-------------- env ---------------'
RUN env

COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
ENTRYPOINT ["redis-server", "/usr/local/etc/redis/redis.conf"]
4个回答

23

这很正常。

docker-compose 只在容器运行阶段设置docker-compose.yaml文件中的 environment 指令中指定的环境变量,而不是在构建阶段设置。

因此,如果您执行 docker-compose run --entrypoint "/bin/bash" redis -c env ,您将能够查看您的环境变量。

如果您想在 Dockerfile 中设置变量(以便在构建阶段看到它们),可以在RUN env之前添加:

ENV FOO bar

当我运行 $ docker-compose run redis env 时,我得到以下错误信息:`*** FATAL CONFIG FILE ERROR *** Reading the configuration file, at line 493
'"env"' Bad directive or wrong number of arguments1`。
- Neil
你是说 docker-compose 在运行 docker compose up redis 的 shell 中设置了那些环境变量吗?如何使 docker-compose 环境持久化到容器中?如果这不是自动完成的,那么 environment 指令的意义是什么? - Neil
1
你提到了“构建阶段”,那么在构建阶段完成后,我在哪里可以获取容器以打印环境变量?我只想让我的运行中的容器能够访问在docker-compose.yml文件中设置的环境变量。 - Neil
让我们在聊天中继续这个讨论 - Aurélien Bottazini
@Neil 修改命令以使用另一个入口点查看所有环境变量。docker-compose run --entrypoint "/bin/bash" redis -c env - Aurélien Bottazini
显示剩余5条评论

2

好的,我已经测试并找到了关于使用环境文件或不使用环境文件的Docker Compose的解决方案。我将向您展示两种不同的方法。

假设您有以下Docker Compose YML文件:

version: '3.8'
services:
db:
image: postgres:13
volumes:
 - "./volumes/postgres:/var/lib/postgresql/data"
ports:
 - "5432:5432"
env_file: docker.env

现在您需要在名为docker.env的文件中设置postgres变量。请记住,您需要将docker_compose.yml文件和docker.env文件放在同一个文件夹中。 接下来,在docker.env文件中,您需要像这样设置数据库变量和值:

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=myapp_db

现在运行 docker-compose up 命令,它应该可以正常工作。 假设你现在不想在 docker-compose.yml 文件中指定 env 文件的名称。那么你需要像这样编写 docker-compose.yml 文件:

version: '3.8'
services:
db:
  image: postgres:13
  volumes:
    - "./volumes/postgres:/var/lib/postgresql/data"
  ports:
    - "5432:5432"
  environments:
     - POSTGRES_USER=${PGU}
     -POSTGRES_PASSWORD=${PGP}
     -POSTGRES_DB=${PGD}

现在你的docker.env文件应该长成这样:

PGU=postgres
PGP=postgres
PGD=myapp_db

现在运行 docker-compose --env-file docker.env up 命令

你已经准备就绪了。


使用env_file要简单得多,而且可以更好地与docker-compose文件分离。此外,如果您有非常嵌套的环境变量,我只能使用单独的.env文件才能让它正常工作,而不是将其包含在compose文件中。 - FlyingV

2
这是因为您在build块内部使用environment,而我猜您想要使用args。请注意修改。
redis:
    build: 
      context: ../storage/redis
      args:
        - FOO: 'bar'
      ports:
        - "6379:6379"

FUN 将在您的 Dockerfile 中如下定义:
FROM redis:2.6

RUN mkdir -p /var/redis && chown -R redis:redis /var/redis

# Read FUN from (build) arguments 
# (may define a default: ARG FUN='wow')
ARG FUN

# Define env variable FUN with value from ARG
ENV FUN=$FUN

RUN echo '-------------- env ---------------'
RUN env

COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
ENTRYPOINT ["redis-server", "/usr/local/etc/redis/redis.conf"]

environment块用于为运行的容器定义变量(当执行docker-compose up时,而不是docker-compose build时)。

类似的问题和答案可能会引起兴趣:


0

简而言之:如果您需要使用环境变量,请使用ENV文件而不是将其放入compose文件中。当将环境变量放置在docker-compose文件(环境变量列表)中并且这些变量相互引用时,docker-loader无法正确地连接这些变量。

解释

长话短说,当环境变量放置在.env文件中时,在提供给运行的docker环境之前进行评估。这允许动态生成特定的环境变量(请参见我的示例,其中连接字符串利用了ENV文件中的环境变量)。

请使用此方法代替。

version: '3.8'
services:
db:
image: postgres:13
volumes:
 - "./volumes/postgres:/var/lib/postgresql/data"
ports:
 - "5432:5432"
env_file: docker.env

docker.env文件包含:

   ASPNETCORE_ENVIRONMENT=Test
    DATABASE_USER=lawguy007
    DATABASE_PASSWORD=myPasswordIsBoring
    DATABASE_SERVER=192.168.1.25    
    ConnectionStrings__DefaultConnection=Server="${DATABASE_SERVER}";Include Error Detail=true;Database=threatlists;User Id=${DATABASE_USER};Password=${DATABASE_PASSWORD}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接