Docker-compose args不会传递给Dockerfile

时间:2019-06-11 12:58:09

标签: docker docker-compose dockerfile

我有一个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

但是,这将失败。 brokerqueue 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上?

2 个答案:

答案 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语法。)