代码之家  ›  专栏  ›  技术社区  ›  Cerin

从docker compose访问shell环境变量?

  •  1
  • Cerin  · 技术社区  · 3 年前

    如何从docker compose内部访问Bash中导出的环境变量?

    我基本上是在尝试 this answer 但我不想定义 .env 文件

    我只想打个电话,比如:

    export TEST_NAME=test_widget_abc
    docker-compose -f docker-compose.yml -p myproject up --build --exit-code-from myproject_1
    

    并通过 TEST_NAME 到我的Dockerfile中的命令,它运行一个单元测试套件,如:

    ENV TEST_NAME ${TEST_NAME}
    
    CMD python manage.py test $TEST_NAME
    

    我的目标是允许运行我的docker容器来执行特定的unittest,而不必重建整个映像,只需在容器运行时从shell中提取测试名称即可。否则,如果未给定测试名称,则该命令将运行所有测试。

    据我所知,您可以在 .env 文件,然后在你的docker-compose.yml中引用它们,比如:

    version: "3.6"
    services:
      app_test:
        build:
          args:
          - TEST_NAME=$TEST_NAME
          context: ..
          dockerfile: Dockerfile
    

    但这并不能从壳里拔出来。

    你将如何与docker compose合作?

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

    对于你描述的设置,我会 docker-compose run 临时集装箱

    export COMPOSE_PROJECT_NAME=myproject
    docker-compose run app_test python manage.py test_widget_abc
    

    这将使用 docker-compose.yml 除了 ports: ,并且它使用您提供的命令,而不是Compose command: 或Dockerfile CMD .它将向 depends_on: 启动相关容器的约束(您可能需要一个入口点包装器脚本来实际等待它们运行)。

    如果测试代码被构建在你的“正常”图像中,你甚至可能不需要特殊的Compose设置来完成这项工作;刚好指向 docker compose run 在您现有的应用程序服务定义中,而不为集成测试定义专用服务。


    既然Compose做到了(简单) environment variable substitution 您还可以提供每次执行 命令: 在Compose文件中

    version: "3.6"
    services:
      app_test:
        build: ..
        command: python manage.py $TEST_NAME # uses the host variable
    

    或者,使用您拥有的Dockerfile,传递主机的环境变量;这个 CMD 将在字符串启动时运行shell来解释该字符串

    version: "3.6"
    services:
      app_test:
        build: ..
        environment:
          - TEST_NAME # without a specific value here passes through from the host
    

    这两种设置都适用于您在问题中显示的Dockerfile和Compose设置。

        2
  •  0
  •   larsks    3 年前

    您的 docker-compose.yaml 将替换为来自环境的值。例如,如果我写:

    version: "3"
    services:
      app_test:
        image: docker.io/alpine:latest
        environment:
          TEST_NAME: ${TEST_NAME}
        command:
          - env
    

    然后如果我导出 TEST_NAME 在我的本地环境中:

    $ export TEST_NAME=foo
    

    并提起堆栈:

    $ docker-compose up
    Creating network "docker_default" with the default driver
    Creating docker_app_test_1 ... done
    Attaching to docker_app_test_1
    app_test_1  | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    app_test_1  | HOSTNAME=be3c12e33290
    app_test_1  | TEST_NAME=foo
    app_test_1  | HOME=/root
    docker_app_test_1 exited with code 0
    

    我明白了 测试名称 容器内部已接收到来自本地环境的值。


    看起来您正试图将环境变量传递到图像构建过程中,而不是在运行时传递它。即使这只起作用一次,也不会有用,因为 docker-compose 不会在每次运行时重新生成图像,因此无论 测试名称 图像构建时 是你在容器里看到的。

    最好在运行时将环境传递到容器中。