我有一个docker-compose.yml
文件,在该文件中,给定服务的构建上下文为Dockerfile
。
示例docker-compose:
version: '3'
services:
scd-service:
build:
context: ./cmd/some-service/
dockerfile: Dockerfile
args:
broker: redis:6379
queue: somequeue
depends_on:
- redis
networks:
- backend
redis:
image: "redis:alpine"
restart: unless-stopped
networks:
- backend
它可以找到Dockerfile
并使用以下内容进行构建:docker-compose up --build some-service
但是,这将失败。 broker
和queue
args永远不会传递到给定的Dockerfile。
示例Dockerfile
:
FROM golang:1.11
// stuff...
ARG broker
ARG queue
CMD ["go", "run", "/go/src/github.com/org/project/cmd/some-service/some-service.go", "--broker $broker", "--queue $queue"]
在构建阶段很明显,它们从未被解析:
Step 7/7 : CMD ["go", "run", "/go/src/github.com/org/project/cmd/some-service/some-service.go", "--broker $broker", "--queue $queue"]
此后,由于命令行参数无效,Go程序崩溃了。
一个如何将docker-compose
的args解析为Dockerfile
?
编辑:很奇怪,我可以回显正确的值吗?
示例:
ARG broker
ARG queue
RUN echo ${broker}
输出:
Step 7/8 : RUN echo ${broker}
---> Running in c84828847d9a
redis:6379
这怎么不解析到CMD上?
答案 0 :(得分:3)
如果希望它们在基于图像的容器(运行侧)上可用,则应将它们设置为ENV
。像这样:
ENV broker $broker //assign your env broker value to container
ENV queue $queue
ARG
这些在创建映像时可用,但在您要基于该映像运行容器时不可用。
ENV
ENV
值可用于容器以及RUN样式的命令。如果您希望自变量在运行时可用,那么这些是不错的选择。
您还会发现有关环境值here的有用信息。
编辑。为了避免 [警告]一个或多个build-args []没有被消耗消息,您应该执行以下操作:
ARG broker=your.broker.value
ENV broker=${broker}
该错误表明您有未使用的ARGS(尽管现在有了ENV,您可能无需设置它们就可以了)。以及here的更多信息。
答案 1 :(得分:2)
这里有两个问题。 ARG
仅在创建映像时在构建时使用,CMD
定义了在运行容器时在运行时的步骤。 ARG
被实现为RUN
步骤的环境变量,因此外壳程序需要扩展环境变量。而且json语法不会运行shell。因此,要使用CMD
进行此操作,您需要进行两项更改。
首先,您需要将ARG
保存为ENV
值,该值将保存到图像元数据中,并在创建容器时用于设置环境。
第二,您需要从exec / json语法切换为运行CMD
来运行将扩展这些变量的shell。 Docker使用字符串语法为您完成此操作。
最终结果如下:
FROM golang:1.11
// stuff...
ARG broker
ENV broker=${broker}
ARG queue
ENV queue=${queue}
CMD go run /go/src/github.com/org/project/cmd/some-service/some-service.go --broker "$broker" --queue "$queue"
顺便说一句,您还应该注意exec语法中的每个参数都必须是一个单独的数组条目,例如:
CMD ["go", "run", "/go/src/github.com/org/project/cmd/some-service/some-service.go", "--broker $broker", "--queue $queue"]
类似于运行:
go run /go/src/github.com/org/project/cmd/some-service/some-service.go "--broker $broker" "--queue $queue"
当您真正想要运行时:
CMD ["go", "run", "/go/src/github.com/org/project/cmd/some-service/some-service.go", "--broker", "your_broker", "--queue", "your_queue"]
类似于:
go run /go/src/github.com/org/project/cmd/some-service/some-service.go --broker "your_broker" --queue "your_queue"
(请注意,我从示例中删除了这些变量,因为它们无法使用exec语法。)