【问题标题】:Trouble understanding Docker Compose environment variables无法理解 Docker Compose 环境变量
【发布时间】:2021-07-13 22:19:59
【问题描述】:

我有一个 Docker Compose 的游乐场项目,文件如下:

version: '3'
services:
    mysql:
        image: 'mysql:8'
        container_name: '${PROJECT_NAME}_mysql'
        hostname: '${PROJECT_NAME}_mysql'
        networks:
            - internal
        ports:
            - '127.0.0.1:${MYSQL_EXPOSE_PORT}:3306'
        volumes:
            - mysql:/var/lib/mysql
        env_file:
            -   ./mysql/.env
        environment:
            MYSQL_EXPOSE_PORT: '${MYSQL_EXPOSE_PORT}'
            MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD}'
            MYSQL_USER: '${MYSQL_USER}'
            MYSQL_PASSWORD: '${MYSQL_PASSWORD}'
volumes:
    mysql:

networks:
    internal:

我的./mysql/.env 是这个:

MYSQL_DATABASE=foobar
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=web
MYSQL_PASSWORD=web

我的.env 文件如下所示:

COMPOSE_PROJECT_NAME=foobar
PROJECT_NAME=foobar

MYSQL_EXPOSE_PORT=33061

MYSQL_DATABASE=foobar
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=web_override
MYSQL_PASSWORD=web_override

我在某处读到env_fileenvironment 创建的变量将在容器本身中可用,而--env-file 提供在处理docker-composer.yml 文件期间可用的变量。

但是运行:

docker-compose -f docker-compose.yml --env-file .env up -d

对我来说会产生意想不到的行为。

  1. 如果我同时省略 env_fileenvironment 配置,MySQL 将由于密码为空而无法启动。来自--env-file 的变量将被忽略。这是否意味着 MYSQL_ROOT_PASSWORD 实际上是容器环境所必需的?

  2. 如果我只输入env_file,MySQL 会启动,但使用来自./mysql/.env 的凭据。它会默默地忽略通过--env-file 选项提供的 .env 文件

  3. 最后,如果我同时输入 env_fileenvironment,由于变量替换,它将尊重来自 --env-file 的值。但是执行到容器中并回显$MYSQL_ROOT_PASSWORD 似乎很少丑陋,并尖叫着等待发生的安全漏洞。

在我看来,我对 Docker Compose 环境变量的工作方式存在根本性的误解。

有人可以澄清一下这些问题吗?

【问题讨论】:

    标签: docker docker-compose environment-variables


    【解决方案1】:

    处理环境变量有两个阶段:

    1. 在 Compose 级别,它采用自己的环境,并读取 docker compose --env-file file,或者如果您未指定该选项,则读取 .env。然后它使用这些环境变量在docker-compose.yml 文件中执行variable substitution
    2. 每个容器都有自己的环境,由 Compose environment:env_file: 指令指定。

    这意味着在外部环境中设置某些内容或将其放入--env-file 文件(第 1 步)不会自动使其对容器可见(第 2 步)。

    这与您的观察一致。在前两种情况下,指定--env-file 不会在每个容器的配置中添加任何内容,它只会影响环境变量的扩展,因此从容器的角度来看它没有任何影响。在第三种情况下,您有正确的顺序:--env-file 在 Compose 级别设置变量,变量替换在 environment: 块中设置固定字符串,然后是 environment: takes precedence env_file:

    【讨论】:

    • 谢谢。这些链接的这种答案正是我所寻求的:)
    猜你喜欢
    • 2015-06-17
    • 2018-12-03
    • 1970-01-01
    • 2022-01-01
    • 2018-02-03
    • 2019-02-25
    • 2022-06-11
    • 1970-01-01
    • 2019-07-26
    相关资源
    最近更新 更多