代码之家  ›  专栏  ›  技术社区  ›  Jovan Perovic

无法理解Docker Compose环境变量

  •  0
  • Jovan Perovic  · 技术社区  · 3 年前

    我有一个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_file environment 创建容器本身中可用的变量,以及 --env-file 提供在处理过程中可用的变量 docker-composer.yml 文件

    但是运行:

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

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

    1. 如果我忽略了这两个 环境文件 环境 configs,MySQL由于密码为空而无法启动。变量来自 --env文件 被忽略。这是不是意味着 MYSQL_ROOT_PASSWORD 事实上作为容器env是必需的吗?

    2. 如果我把 环境文件 仅,MySQL启动,但使用来自的凭据 ./mysql/.env 。它会忽略通过提供的.env文件 --env文件 选项

    3. 最后,如果我把两者都放进去 环境文件 环境 ,它将尊重来自的价值 --env文件 由于变量替换。但是执行到容器中并回显 $MYSQL_ROOT_PASSWORD 看起来很少丑陋,并尖叫着安全漏洞等着发生。

    在我看来,我对Docker Compose env变量的工作方式有一个根本的误解。

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

    0 回复  |  直到 3 年前
        1
  •  1
  •   David Maze    3 年前

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

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

    这意味着把一些东西放在外部环境中或放在 --env-file 文件(步骤1)不会自动使其对容器可见(步骤2)。

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