您好,有没有办法在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"
嗨@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}" )
如何使用:
要么
注意事项:
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中的名称-
您收到此消息是因为您已订阅此线程。
直接回复此电子邮件,在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,对于设置uid
和gid
而不会使解决方案过于复杂非常有用
```
/ _ / \
(哦)
^ <```
+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
最有用的评论
拥有...将非常有用。