gpt4 book ai didi

c++ - 通过 docker multistage build vs mount 构建和部署 C++

转载 作者:行者123 更新时间:2023-12-01 23:15:21 25 4
gpt4 key购买 nike

我正在尝试使用具有许多自定义库依赖项的 docker 构建自定义 C++ 工具。

共有三个库:libA、libB 和 libC。 libB 依赖于 libA,libC 依赖于 libA 和 libB。在我的家庭系统上,我通常会更新 libA 的源代码,然后安装它下游的所有内容,因为 libB 使用 CMake 来查找 libA 等。

在 docker 中实现此目标的最佳方法是什么?是不是也要用make install?我不希望包含源代码的最终图像 - 只是二进制文件和库。如果我使用多阶段构建,我怎么知道我已经复制了所有必要的其他库,例如将 protobuf curl 到最后的“层”。只挂载构建镜像的源代码而不是部署镜像的源代码不是更好吗?

我发现关于 docker 和 C++ 的信息不多。

最佳答案

您通常不想为您的应用程序代码或依赖项使用卷。最佳做法是使 Docker 镜像独立。您可能会遇到大量使用卷和绑定(bind)挂载的解释语言(尤其是 Node)的 Docker 设置,但这些实际上只是通过 Docker 在主机代码上运行 Node,而不是在主机上安装 Node。

对于需要编译但只需要运行编译后的工件的东西,一种典型的方法是使用 Docker multi-stage build .这个想法是,您设置一个包含完整构建工具链的镜像并编译所有内容,然后在同一个 Dockerfile 中创建第二个镜像,COPY --from 第一个镜像仅包含已编译的工件。

我可能会在这里尝试使用标准的 /usr/local 目录树,原因有二:它通常是 Autoconf 等工具的默认安装前缀,并且在标准 Linux 发行版 Docker 镜像中它是空的。

# The first stage only builds things.  We'll COPY files out of it
# later.
FROM ubuntu:20.04 AS builder

# Install any dependencies we need here, like the C toolchain.
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --assume-yes --no-install-recommends \
build-essential \
libbar-dev \
libfoo-dev \
libquux-dev

# Build library A and install it into /usr/local.
WORKDIR /usr/src/libA
COPY libA ./
RUN ./configure \
&& make \
&& make install

# Similarly with library B
WORKDIR /usr/src/libB
COPY libB ./
RUN ./configure \
&& make \
&& make install

# ...and library C, and the application proper
...

# The final FROM line is the actual runtime image. Anything before
# this will be built, and will show up in `docker images`, but isn't
# "the output" of the build.

FROM ubuntu:20.04

# Get the installed libraries and applications from the earlier stage.
COPY --from=builder /usr/local/ /usr/local/

# Regenerate the shared-library cache.
RUN ldconfig

# Set ordinary metadata to run a Docker container. (The binary is
# probably in /usr/local/bin which is on the default PATH.)
EXPOSE 80
CMD ["myapp"]

如果不同的库具有非常不同的构建时依赖性,则可以扩展此方法以拥有更多构建阶段。请记住,每个 FROM 行都重新开始,您需要 RUN apt-get installCOPY 东西到每个图像阶段才能显示它们.

这里的一个开放的并发症是 C 库构建通常会包含一些仅在额外的 C 库构建中需要的部分。在您的示例中,libB 依赖于 libA,因此 libA 安装步骤将包括 C 头文件,通常还包括一个静态库。它们可能很大(尤其是 .a 静态库)并且在运行时不需要。您可能想要清除这些,也许通过在构建阶段结束时战略性地使用 RUN rm。一般来说,RUN rm 不会使图像变小,但是如果您在构建阶段RUN rm 某些内容,然后将编辑后的文件COPY 到最后阶段,只有留下的东西被复制到最终图像中。

关于c++ - 通过 docker multistage build vs mount 构建和部署 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69011431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com