如何在开发和生产环境中使用相同的Dockerfile。

3

我有两个Dockerfile,一个用于开发环境,另一个用于生产环境:

生产环境:

FROM golang AS builder
WORKDIR /go/src/gitlab.com/company/project
COPY . .
RUN go build -o ./release/api .

FROM scratch
EXPOSE 9999
COPY --from=builder /go/src/gitlab.com/company/project/release/api .
CMD ["./api"]

和 DEV:

FROM golang
WORKDIR /go/src/gitlab.com/company/PROJECT
COPY . .
RUN go build -o ./release/api .
CMD ["./release/api"]

我希望将这两个合并为一个,因为维护两个Dockerfile是一种不好的做法
主要区别在于开发时使用实用的golang镜像,而在生产中使用减小了二进制文件大小的scratch镜像。
似乎可以在一个Dockerfile中使用多个阶段,并在构建时指定阶段名称:
docker build . --target=builder

但是如果我这样做,我不知道如何在第一阶段有条件地运行我的应用程序=[如果我处于开发状态,则在第一阶段运行应用程序,否则在第二阶段运行应用程序]

我该怎么做?


只是一个问题,你想在测试和生产环境中使用两个不同的镜像作为基础,有什么原因吗?首先使用Docker的主要原因之一是镜像上的底层操作系统和依赖项对于每个环境都是相同的。 - Blokje5
1
好吧,我不想在一个空白镜像上进行开发,里面什么都没有,不太实用。而且我也不想在生产环境中使用golang镜像,因为它太大了。 - Juliatzin
可能是如何为开发和生产配置不同的Dockerfile的重复问题。 - Murtaza Hussain
为什么不在您的主机上安装Go工具链并用于开发呢? - David Maze
1个回答

2
这样行吗?我没有测试过,也没有深入思考你的例子,但或许这个方案能够接近你所需要的,或者帮助你找到最终解决方案?"
FROM golang:alpine AS base
WORKDIR /go/src/gitlab.com/company/project
COPY . .
RUN go build -o ./release/api .

FROM base AS dev
CMD ["./release/api"]

FROM scratch AS prod
EXPOSE 9999
COPY --from=base /go/src/gitlab.com/company/project/release/api .
CMD ["./api"]

根据在目标中指定的值docker build --target=proddocker build --target=dev,将构建不同的镜像。"Original Answer"翻译成"最初的答案"。

1
做到了!我没有使用 FROM ${BUILD_ENVIRONMENT},而是使用 docker build --target=prod... 建立生产环境,使用 docker build --target=dev... 建立开发环境。 - Juliatzin
你的解决方案比这里的更简单、更好:https://dev59.com/AlYO5IYBdhLWcg3wDNbI - Juliatzin
让我们将其更新到答案中,以便它符合您的问题 :) - Javier Aviles
这种方法唯一的问题是,我使用它几天后发现,如果我使用 docker build --target=prod 命令,它也会执行 dev 部分,这部分是没用的。它不是一个过滤器,但它可以让你运行部分 Dockerfiles。 - Juliatzin
为什么不在第一个镜像中包含 CMD ["./release/api"],并将 "AS base" 重命名为 "AS dev",然后它就会停在那里,但如果是 prod,则会构建下一个镜像?CMD ["./release/api"] 不应影响第一个镜像中的任何内容。 - Javier Aviles
是的,但我现在正在处理另一个 NodeJs 的案例,并根据环境安装不同的库,所以它可以工作,但构建需要更多时间。 - Juliatzin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接