Compose: 在docker-compose.yml中使用shell命令

创建于 2016-10-27  ·  41评论  ·  资料来源: docker/compose

您好,有没有办法在docker-compose.yml文件中使用Shell命令?
这是我的用例:

 version: '2'
 services:
   ci:
     image: jenkins
     volumes:
       - ./data:/var/jenkins_home
       - /var/run/docker.sock:/var/run/docker.sock
       - $(command -v docker):/usr/bin/docker
     groupadd:
       - $(stat -c %g /var/run/docker.sock)
     ports:
       - "8080:8080"
       - "50000:50000"

目前,这给了我这个错误:

ERROR: Invalid interpolation format for "volumes" option in service "ci": "${command -v docker}:/usr/bin/docker"
kinquestion

最有用的评论

拥有...将非常有用。

所有41条评论

@zkanda

抱歉,我们不支持此功能。 通常,这是通过设置环境变量并在Compose文件中使用变量替换来完成的。

@ shin-谢谢,我可以解决环境变量。 .env似乎也非常有用。
相关文档: https: //docs.docker.com/compose/environment-variables/#/-env文件

@zkanda您是否曾经使用过此工具,我在.env文件中尝试过

DOCKER_BIN=`which docker`

然后在docker-compose.yml中

jenkinsmaster:
  build: jenkins-master
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ${DOCKER_BIN}:/usr/bin/docker
  ports:
    - "50000:50000"

但我不断

Cannot create container for service jenkinsmaster: create `which docker`: "`which docker`" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.

因此,看起来命令在.env文件中被解释为字符串了吗?

命令不会在.env或其他地方由Compose扩展。

拥有...将非常有用。

+1

这是一个用例。 设置Kafka时,它需要主机的IP。 我有以下脚本可以帮助我实现这一目标:

DOCKER_HOST_IP=$(ifconfig | grep 'inet .*br' | sed -E 's/.*inet (.*) netmask.*/\1/')

我在环境中引用了该IP。 我不能只运行docker-compose up ,因为我需要事先运行。 我需要将此信息告知团队中的其他开发人员。

+1

获取当前用户将很有用,例如:

services:
  foo:
    image: bar:latest
    user: ${CURRENT_USER-$(id -u):$(id -g)}

也必须有其他用例...

顺便说一句,如果我们无法执行其余的Bash功能,我不会得到${BAZ-default}在Compose中有效的事实(据我所知, -是Bash的变量操作功能之一,例如用${VAR/search/replace}代替)

是的@ davi5e ...我想要的是:

version: "3.7"

services:
  orchestrator:
    build: .
    ports:
      - "2000:2000"
    # Use type host until we can test link
    network_mode: "host"
    environment:
      - NODE_ENV=development
      - LOCAL_USER_ID=${id -u}

@ davi5e的另一个用例是,当您要创建

+1
请重新打开问题

+1
我的用例是发布根据“基本”端口而确定的端口范围

这对于设置UID / GID变量非常有用,因为在开发环境中使用Docker几乎是一项要求(无需使用脚本将其设置为.env文件)。

+1

可以使用它来标记/标记由docker生成的图像,并使用git标签组成并提交哈希值:

.env

GIT_VERSION=$(git describe --always --dirty --abbrev)
OUTER_PORT=6970

docer-complse.yml

version: '3'
services:
  nginx:
    restart: always
    build:
        context: ./nginx
        labels:
          org.label-schema.schema-version: "1.0"
          org.label-schema.version: "${GIT_VERSION}"
          org.lavel.schema.url: "https://mydocu-server.company.com/vcs/${GIT_VERSION}"
    ports:
      - ${OUTER_PORT}:8080

对于那些在开发中执行此操作的人,如果您的shell设置了UID变量,则可以在构建本地开发映像时将其传入。 由于不共享本地开发映像,因此您不必担心与同事之间的uid冲突。

+1

@ con-f-use这样做只会发送实际的命令,而不是测试的结果,到目前为止,我唯一成功的技巧就是编写包裹docker compose的脚本,该脚本设置了环境变量。

+1

TL; DR,如果要从.env文件中导出这些变量:

# set the path of .env file here
ENV_FILE="${ENV_FILE:-local.env}"
while IFS= read -r line; do
  export "$line"
done < <( grep --color=never -E -v -e '^#' -e '^[[:space:]]*$' "${ENV_FILE}" )

如何使用:

  • 在命令行上键入它,然后按Enter键以修改当前的Shell环境。

要么

  • 将其另存为bash脚本并进行来源

注意事项:

  • 将其另存为脚本并运行它不会神奇地在当前Shell环境中导出这些变量。 您必须将其来源或花哨的eval
  • (也许是一件好事?)它将覆盖$ENV_FILE具有相同名称的现有变量

说明:这里

看看direnv可以自动化所有https://direnv.net/

2019年6月28日星期五,下午12:57 Sudarshan Wadkar [email protected]
写道:

TL; DR,如果要从.env文件导出这些变量:

在这里设置.env文件的路径

ENV_FILE =“ $ {ENV_ FILE:-local.env }”而IFS =读-r行; 做
导出“ $ line”完成<<(grep --color = never -E -v -e'^#'-e'^ [[:space:]] * $'“ $ {ENV_FILE}”)

如何使用:

  • 在命令行上输入
  • 将其另存为bash脚本并进行来源

注意事项:

  • 将其保存为脚本并运行它不会神奇地导出那些
    当前shell环境中的变量。 您必须采购它或做
    一些花哨的评估。
  • (也许是一件好事?)它将用相同的名称覆盖现有变量
    $ ENV_FILE中的名称

说明:这里
https://explainshell.com/explain?cmd=while+IFS%3D+read+-r+line%3B+do+export+%22%24line%22%3B+done+%3C+%3C%28grep+--color%3Dno+ -v + -e +%27%5E%23%27 + -e +%27%5E%5B%5B%3Aspace%3A%5D%5D *%24%27 +%24%7BENV_FILE%7D%29

-
您收到此消息是因为您已订阅此线程。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDBQXQQZTC5FXTOFL6UTP4XOBJA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORment
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACHRDGJ6FAQBEDLBSRVS6TP4XOBJANCNFSM4CUISSSA

是的, direnv很好,但是我不确定它是否对Docker的.env文件有用,该文件具有简单的行并带有简单的VAR=VAL语法(如此链接所示)。想法是将.env文件提交到存储库,并且构建脚本可以在我的本地运行该脚本,或者docker-compose可以在登台/部署中运行它。

确实没有环境变量
https://en.wikipedia.org/wiki/Environment_variable,如果它们属于
代码库,而不是环境的一部分...

2019年6月28日星期五,下午2:04 Sudarshan Wadkar [email protected]
写道:

是的,direnv很好,但是我不确定它是否对Docker有用
.env文件,其简单行使用简单的VAR = VAL语法(按此
https://docs.docker.com/compose/env-file/#syntax-rules链接。)
将.env文件提交到存储库,并且构建脚本可以
在我的本地或docker-compose上运行它可以在登台/部署上运行它。

-
您收到此消息是因为您已订阅此线程。
直接回复此电子邮件,在GitHub上查看
https://github.com/docker/compose/issues/4081?
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACHRDF3Q3YOZPHUIUZYEPTP4XV5BANCNFSM4CUISSSA

哦好的。

我想认为.env文件在执行docker-compose up时会变成环境变量。

我的用例是使用相同的.env文件作为运行本地dev实例的真理源(可能没有docker-compose )。 是的,也许.env文件中的那些行并不是真正的环境变量,但是当您部署时它们肯定会变成一个。

在这种情况下,我仍然看不到direnv有什么帮助。

另一个用例是放置一个生成密码的命令,将该密码分配给容器中的env var。
这样一来,密码实际上就不会写入.env或docker-compose.yml文件中。

我认为这将对许多与安全性相关的用例产生巨大的好处。

+1

+1

+1,对于设置uidgid而不会使解决方案过于复杂非常有用

```
/ _ / \
(哦)

^ <```

+1我有一个上述用例,用于添加git分支并提交到compose文件中,该文件最终将进入dockerfile,然后作为一个版本添加到在多阶段docker构建过程的一个阶段中构建的jar清单中。

  gateway:
    image: name
    build:
      context: ./project
      dockerfile: build/Dockerfile
      args:
        - GIT_COMMIT=${$(git rev-list -1 HEAD):-unspecified}
        - GIT_DATE=${$(git log -1 --date=short --pretty=format:%ct):-unspecified}

因此,当前,对于我的撰写文件中的7个项目,我必须设置7x2环境。 伤心。

@ shin-您可以重新打开它作为功能请求吗? 似乎尚未通过良好的解决方法来解决它,并且对此有一定的需求。

+1可能可以通过其他方式实现此目的,但是我需要从容器内部使用docker引擎来重新启动相邻的容器。 如果我的Letsencrypt证书已过期,但是我需要在续订后重新启动NGinx容器。 问题是,如何告诉容器内部的docker-compose这组容器的项目名称是什么? PROJECT=(basedir ~+) 。 现在是手动编码的:(

为该功能请求+1
另一个用例是从cli / http中获取秘密(例如Vault,1Password)并插入环境。

...
    environment:
      - SERVICE_USERNAME=$(vault kv get -field=username kv/service/credentials)
      - SERVICE_PASSWORD=$(vault kv get -field=password kv/service/credentials)
...

我和@rafaelbattesti有相同的需求,除了我使用的是lastpass。

...
     environment:
         - TRPASSWD=$(lpass show --password Transmission)
....

+1

+1

@ shin-您可以重新打开它作为功能请求吗? 似乎尚未通过良好的解决方法来解决它,并且对此有一定的需求。

@ four43 ,也许

docker-compose文件中的变量扩展将是一个非常有用的功能...

+1

@esale-是的,我想这取决于情况。 在这种情况下,我可以看到它超出了范围。 不要过多地使用某些DSL。 那时模板与其他工具一起组成了docker-compose文件? 我们过分关注吗?

如果您使用的是.env文件,则可以使用以下命令替换shell输出

eval "echo \"$(cat .env.example)\"" > .env

示例.env.example文件

DOCKER_BIN=$(which docker)
DOCKER_COMPOSE_BIN=$(which docker-compose)

创建.env文件

DOCKER_BIN=/snap/bin/docker
DOCKER_COMPOSE_BIN=/snap/bin/docker-compose
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

bitver picture bitver  ·  3评论

davidbarratt picture davidbarratt  ·  3评论

squeaky-pl picture squeaky-pl  ·  3评论

DhairyashilBhosale picture DhairyashilBhosale  ·  3评论

maltefiala picture maltefiala  ·  3评论