【问题标题】:Use one dockerfile to build from two different sources使用一个 dockerfile 从两个不同的源构建
【发布时间】:2018-12-20 07:42:17
【问题描述】:

我想使用 git 源或已构建的应用程序创建一个 docker 映像。我创建了两个这样的 Dockerfile(注意:这是伪代码):

运行时图像:

FROM <baseimage>
EXPOSE 1234/tcp
EXPOSE 4321/tcp
VOLUME /foobar
COPY myapp.tgz .
RUN tar -xzf myapp.tgz && rm -f myapp.tgz
ENTRYPOINT ["myapp"]

myapp.tgz 是在构建服务器上创建的,或者可能通过手动编译来创建。它在本地的 docker 主机服务器上可用。

直接从我使用的源代码构建:

FROM <devimage> AS buildenv
ARG GIT_USER
ARG GIT_PASSWORD
RUN    git clone http://${GIT_USER}:${GIT_PASSWORD}@<my.git.host>
RUN    ./makefile && cp /source/build/myapp.tgz /drop/myapp.tgz

FROM <baseimage> AS runenv
EXPOSE 1234/tcp
EXPOSE 4321/tcp
VOLUME /foobar
COPY --from=buildenv /drop/myapp.tgz .
RUN tar -xzf myapp.tgz && rm -f myapp.tgz
ENTRYPOINT ["myapp"]

第二个构建阶段的指令显然是 Runtime-Image Dockerfile 的重复

我只想要一个 Dockerfile,它可以根据需要从源代码或 docker 主机上的上下文构建。我可以将重复的命令放在自定义基础映像中,然后重复使用它来构建 (FROM),但这会混淆 Dockerfile。

推荐的最优雅的方法是什么?

  • 我不能使用绑定挂载在 docker 主机的当前目录中获取myapp.tgz,可以吗?为此,我必须启动 Container 来构建我的应用程序?
  • Dockfile 中没有IF 指令用于条件?
  • 如果docker主机上没有myapp.tgzCOPY myapp.tgz .会失败
  • 如果没有buildenvCOPY --from=buildenv /drop/myapp.tgz . 会失败。

我可以使用COPY ./* . 然后检查

[ -f /myapp.tgz ] && <prepare-container> || <build-from-git-source>

我猜?我们希望您只创建一个单独的 Dockerfile 仅用于从源代码构建,然后使用类似

docker run --rm -v /SomewhereOnHost/drop:/drop my-compile-image

【问题讨论】:

  • 最简单的做法似乎是始终在主机上进行构建;你可以编写一个 shell 脚本来执行任何 make 过程,然后运行 ​​docker build
  • @DavidMaze 不幸的是,我们的一些构建服务器不支持 Docker(Windows Server 2012 和 Centos 6.5)所以我已经单独的 docker 服务器,我无法设置 Jenkins 等(不允许到)

标签: docker dockerfile


【解决方案1】:

在过去的 2 天里,我一直在尝试解决这个问题,现在我有一个很好的解决方案来实现条件构建(Dockerfile 中的 if

ARG mode=local

FROM alpine as build_local 
ONBUILD COPY myapp.tgz .

FROM alpine as build_remote
ONBUILD RUN git clone GIT_URL
ONBUILD RUN cd repo && ./makefile && cp /source/build/myapp.tgz .

FROM build_${mode} AS runenv
EXPOSE 1234/tcp
EXPOSE 4321/tcp
VOLUME /foobar
RUN tar -xzf myapp.tgz && rm -f myapp.tgz
ENTRYPOINT ["myapp"]

顶级mode 允许您通过docker build --build-arg mode=remote . 的条件。使用ONBUILD,因此只有选择了相应的分支,才会执行该命令。

【讨论】:

  • 很好,我忽略了文档中的 ONBUILD 命令。使用这种方法,可以轻松添加其他构建路径,例如从文件服务器下载发布二进制文件并将其用作上下文(我的用例之一)
猜你喜欢
  • 2023-03-04
  • 2018-01-13
  • 1970-01-01
  • 2023-01-04
  • 1970-01-01
  • 2021-01-05
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多