首页 > 解决方案 > 仅用于程序构建的 Docker 容器,无需运行

问题描述

我有一个非常简单(我认为)的问题。拥有只负责构建项目的 docker 容器是个好主意吗?我想在一个容器(容器 A)中构建一个项目,然后将目标文件和库从 docker 卷中的容器 A 共享到另一个容器(容器 B),在该容器中我想将目标文件用作目标程序中的参数(容器 B)。这有点难以描述,所以如果你需要它,我会尝试更多地解释它。非常感谢您的帮助。

编辑:好的,我会尝试描述我的情况。容器 B 包含一个用于复杂计算(模拟等)的程序。我的目标是创建一个将接收 Dockerfile 作为输入的应用程序,然后我将希望以编程方式构建一个映像并运行 Docker 容器(结果我将在容器 A 中构建项目)。接下来,我想将输出(二进制文件、类文件、库等)从容器 A 传递到容器 B 以运行模拟(例如:simulation run myfilefromcontainerA)。之后,我需要收集模拟结果文件并在主机级别的应用程序中处理它们。

标签: dockerdevops

解决方案


在某些情况下,拥有一个仅包含构建工具的容器是合理的。但是,不要代码或二进制文件放在 Docker 卷中;使用该构建工具容器来构建您的应用程序,并将其用作多阶段构建的第一阶段。

假设您有一个仅构建工具的映像。也许看起来像:

FROM ubuntu:18.04
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      build-essential \
      ... libfoo-dev ...
# no EXPOSE, USER, CMD, &c.

现在你有一个本地源代码树,所以你可以调用那个图像

sudo docker run \
  --rm \
  -v "$PWD:$PWD" \
  -w "$PWD" \
  -u $(id -u) \
  my/build-tools \
  ./build-everything.sh

这涉及到并且需要在系统上具有与管理员等效的权限(/etc/sudoers例如,您可以轻松地使用此调用来覆盖主机的文件),因此我不建议将其用于日常使用。它在两个地方很有价值:

  1. 您有一个包含大量副本的 CI 系统。在 CI 系统可以运行并且您可以自由更新的映像中安装构建工具比将所有副本更新到更新的工具链更容易。
  2. 您的构建系统有很多主机级别的依赖项,因此针对一组特定的已知良好版本进行本地测试非常重要。

如果您想将此作为以后构建的基础,您可以。您通常希望构建的结果是一个 Docker 镜像,您可以在其他地方推送和运行该镜像。在多阶段构建中使用它可能如下所示:

FROM my/build-tools AS build
WORKDIR /build
COPY . ./
RUN ./build-everything.sh

FROM ubuntu:18.04
RUN apt-get update ... # to install runtime dependencies only
COPY --from=build /build/the_app /usr/bin/the_app
CMD ["the_app"]

推荐阅读