使用一个dockerfile从两个不同来源构建

时间:2018-11-28 20:49:45

标签: docker dockerfile

我想使用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"]

第二个构建阶段中的指令显然是运行时映像Dockerfile的重复

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

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

  • 我无法使用绑定安装在码头主机的当前目录中获取myapp.tgz,可以吗?为此,我必须启动Container来构建我的应用程序吗?
  • Dockfile中没有IF指令用于条件吗?
  • 如果Docker主机上没有myapp.tgz,则COPY myapp.tgz .将失败
  • 如果没有buildenv,则COPY --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

1 个答案:

答案 0 :(得分:1)

在过去的两天里,我一直试图弄清楚这一点,现在我有一个很好的解决方案来实现条件构建(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以便仅在选择了相应分支的情况下才执行命令。