当前的问题是:如果我需要在 Docker 中的阶段构建之间复制数百个依赖库,那么如何在不达到最大深度的情况下完成此操作?
我最终想要做的是:构建一个尽可能小的包含 python 和 ffmpeg 的容器映像,以供 AWS Lambda 使用。
我知道我能做的是:
FROM ubuntu:latest AS build
RUN apt-get update && apt-get clean && apt-get install -y ffmpeg
FROM python:3.12-slim-bookworm
COPY --from=build /usr/bin/ffmpeg /usr/bin/ffmpeg
COPY --from=build /usr/lib/aarch64-linux-gnu/* /usr/lib/aarch64-linux-gnu/
WORKDIR /app
CMD ["foo"]
生成一个有效的容器镜像,但是它非常大,超过 1 GB。
我想复制 ffmpeg 及其依赖项,但这就是问题所在。ldd
告诉我 /lib 中有超过 200 个依赖项,并且有这么多COPY
语句会导致在构建期间超出最大深度。尝试避免:
COPY --from=build /usr/lib/lib1 /usr/lib/lib1
COPY --from=build /usr/lib/lib2 /usr/lib/lib2
...
COPY --from=build /usr/lib/lib227 /usr/lib/lib227
有没有办法从外部 txt 文件循环进入 Dockerfile,或者其他机制来复制数百个依赖项而不超出最大深度?
看起来 ffmpeg 就是这么大。如果我尝试在一个新的干净的 Ubuntu 容器中安装 ffmpeg
现在,其中一些是你不一定需要的文件格式和设备驱动程序。这些是通过 Debian“推荐”的依赖项类型提供的,你可以
apt-get install --no-install-recommends
。这很有帮助,但只有一些除非您有充分理由相信,即使这组软件包也引入了运行该工具所不需要的额外文件,否则您将不得不使用几百兆大的图像。(如果您认为存在不必要的依赖关系,提交 Debian 或 Ubuntu 错误报告可能是有意义的。)
原则上,您无需执行一堆小
COPY
操作,而是可以在第一个图像中组装一个临时树,其中包含您需要的文件COPY
,然后只需将它们移动一次即可。这也意味着您可以通过编程来完成。也许这有望可靠地(直到解析
ldd
的输出)收集程序所依赖的所有 C 共享库。但这不一定是您真正需要的所有文件;例如/usr/share/ffmpeg
,ffmpeg 本身包含 中的少量文件,而追踪这些文件是一个非常开放的问题。如果您成功完成此操作,您可能已经重新创建了安装的确切文件apt-get install ffmpeg
。