10 个稳定版本
1.4.0 | 2022年12月12日 |
---|---|
1.3.2 | 2022年11月23日 |
1.3.1 | 2022年6月19日 |
1.3.0 | 2022年3月5日 |
0.1.0 | 2020年4月3日 |
#688 in 开发工具
每月35次下载
89KB
2.5K SLoC
magicpak
magicpak
允许您在不进行任何繁琐准备(如静态链接)的情况下构建最小 Docker 镜像。
# You prepare /bin/your_executable here...
ADD https://github.com/coord-e/magicpak/releases/download/v1.4.0/magicpak-x86_64-unknown-linux-musl /usr/bin/magicpak
RUN chmod +x /usr/bin/magicpak
RUN /usr/bin/magicpak -v /bin/your_executable /bundle
FROM scratch
COPY --from=0 /bundle /.
CMD ["/bin/your_executable"]
就是这样!生成的镜像将只包含您的可执行文件在运行时所需的文件。您可以在 example/ 下找到更多有用的 magicpak
示例。
功能
magicpak
是一个命令行工具,用于分析并打包可执行文件的运行时依赖项。 magicpak
主要收集在运行时由动态链接器所需的共享对象依赖项。此外,magicpak
的贡献总结如下
- 简单。您只需在您的
Dockerfile
中添加几行即可构建最小镜像。 - 功能全面。您可以一次打包、测试和压缩您的可执行文件。您可以专注于您的业务,因为
magicpak
处理所有与Dockerfile
相关的事项,以减小镜像大小。 - 动态分析。
--dynamic
标志启用动态分析,可以发现除动态链接库之外的依赖项。 - 灵活。我们通过一系列选项(如
--include
和--exclude
)提供了对生成捆绑包的完全控制。您可以处理无法自动检测的依赖项。 - 稳定。我们不解析未记录的且有时不准确的反汇编器(ldd(1))输出。相反,我们使用 glibc 中的 dlopen(3) 和 dlinfo(3) 来查询共享库的位置以供 ld.so(8) 使用。
magicpak
特别适用于您发现难以生成静态链接可执行文件的情况。当从源代码构建麻烦或源代码不公开时,magicpak
也非常有用,因为 magicpak
只需要可执行文件来构建最小 Docker 镜像。
用法
您可以从以下命令开始:magicpak path/到/可执行文件路径/到/输出
。这会静态分析您可执行文件的运行时依赖项,并将可执行文件运行时所需的所有内容放入指定的输出目录。一旦捆绑,我们就可以简单地将其复制到第二阶段中的scratch
镜像中,如下所示。
RUN magicpak path/to/executable /bundle
FROM scratch
COPY --from=0 /bundle /.
有些可执行文件以这种方式运行良好。然而,其他一些由于magicpak
的静态分析不足以在运行时检测到它们所需的全部文件,因此无法正常运行。对于这种情况,magicpak
提供了--include <GLOB>
选项来手动指定缺失的需求。此外,您可以使用--dynamic
来自动包含在执行过程中被可执行文件访问的文件。
尽管我们的实现非常谨慎,但我们的分析在某种程度上是不可靠的,因为我们无法在执行之前完全确定其运行时行为。为了确保magicpak
收集了执行特定任务所需的所有依赖项,我们实现了--test
选项。--test
可以通过chroot(2)测试结果捆绑。
结果镜像的大小是我们主要关注的问题。magicpak
支持使用upx
进行可执行文件压缩。您可以通过--compress
启用它。
支持的选项
Usage: magicpak [OPTIONS] <INPUT>... <OUTPUT>
Arguments:
<INPUT>... Input executable
<OUTPUT> Output destination
Options:
-i, --include <GLOB> Additionally include files/directories with glob patterns
-e, --exclude <GLOB> Exclude files/directories from the resulting bundle with glob patterns
--mkdir <PATH> Make directories in the resulting bundle
-r, --install-to <PATH> Specify the installation path of the executable in the bundle
--log-level <LEVEL> Specify the log level [default: Warn] [possible values: Off, Error, Warn, Info, Debug]
-v, --verbose Verbose mode, same as --log-level Info
-t, --test Enable testing
--test-command <COMMAND> Specify the test command to use in --test
--test-stdin <CONTENT> Specify stdin content supplied to the test command in --test
--test-stdout <CONTENT> Test stdout of the test command
-d, --dynamic Enable dynamic analysis
--dynamic-arg <ARG> Specify arguments passed to the executable in --dynamic
--dynamic-stdin <CONTENT> Specify stdin content supplied to the executable in --dynamic
-c, --compress Compress the executable with npx
--upx-arg <ARG> Specify arguments passed to upx in --compress
--busybox <PATH or NAME> Specify the path or name of busybox that would be used in testing [default: busybox]
--upx <PATH or NAME> Specify the path or name of upx that would be used in compression [default: upx]
--cc <PATH or NAME> Specify the path or name of c compiler that would be used in the name resolution of shared library dependencies [env: CC=] [default: cc]
--experimental-noload-resolver [EXPERIMENTAL] Resolve dynamic library paths without loading in dlopen(3)
-h, --help Print help information
Docker镜像
我们提供了一些基础镜像,其中包含magicpak
及其可选依赖项,以便您开始使用。
名称 | 描述 |
---|---|
magicpak/debian |
library/debian带有magicpak |
magicpak/cc |
library/debian带有build-essential 、clang 和magicpak |
magicpak/haskell |
library/haskell带有magicpak |
magicpak/rust |
library/rust带有magicpak |
示例
以下是一个使用magicpak
为C/C++/等格式器clang-format
创建Docker镜像的Dockerfile,clang-format
是一个格式化工具。(example/clang-format)
FROM magicpak/debian:buster-magicpak1.4.0
RUN apt-get -y update
RUN apt-get -y --no-install-recommends install clang-format
RUN magicpak $(which clang-format) /bundle -v \
--compress \
--upx-arg --best \
--test \
--test-stdin "int main( ){ }" \
--test-stdout "int main() {}" \
--install-to /bin/
FROM scratch
COPY --from=0 /bundle /.
WORKDIR /workdir
CMD ["/bin/clang-format"]
关于名称解析和glibc的说明
如果您的程序使用glibc进行名称解析(很可能是这样),在通过magicpak捆绑后,对getaddrinfo(3)的调用将导致错误。可以通过手动包括以下示例中的NSS相关共享库来解决这个问题。
# example on x86_64 Debian-based image:
RUN magicpak path/to/executable /bundle --include '/lib/x86_64-linux-gnu/libnss_*'
关于jemalloc的说明
如果您的程序依赖于libjemalloc,magicpak可能会失败,并显示以下消息。
error: Unable to lookup shared library: /lib/aarch64-linux-gnu/libjemalloc.so.2: cannot allocate memory in static TLS block
您可以使用--experimental-noload-resolver
标志来解决这个问题。有关详细信息,请参阅#19。
免责声明
magicpak
没有任何保证。无法保证处理的捆绑包能够正确且相同地工作。虽然我在使用magicpak
构建各种类型的镜像时没有遇到问题,但建议您谨慎使用,并对生成的捆绑包进行仔细检查。
许可证
根据以下之一获得许可
- Apache License,版本2.0(LICENSE-APACHE或https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由你选择。
贡献
除非你明确说明,否则任何由你有意提交并包含在作品中的贡献,根据Apache-2.0许可证的定义,应按照上述方式双许可,不附加任何额外条款或条件。
依赖项
~6–16MB
~214K SLoC