build: docker runtime build is not reproducible
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 领域
- build-system, devops
调研方向
阅读 scripts/docker/Dockerfile、scripts/build-runtime.sh、scripts/common/install-dependencies.sh 和 src/runtime/Makefile,然后构建 Docker 镜像并比较多次运行得到的 runtime 输出。完成的标准是:从相同源代码构建能够生成逐字节完全一致的二进制文件,并且在不破坏现有构建的情况下纳入可复现性改动。
由索引模型根据 Issue 内容生成。
描述
The current docker build of the type2-runtime is not reproducible, which means compiling it on different machines or at different times produces binaries that are not byte-for-byte similar (different hash).
This is an issue for downstream projects trying to distribute appimages in a reproducible way so users can easily verify the appimage actually contains the source code at a specific commit by building the appimage themselves and comparing it against the distributed appimage.
Currently i apply the following patch on the type2-runtime repo at commit 5e7217b7cfeecee1491c2d251e355c3cf8ba6e4d to make the build more reproducible.
Some parts might be overkill but it would be great if the type2-runtime project could consider reproducibility in their development process and incorporate some trivial changes like pinning versions in the docker image to make it simpler to use for downstream projects.
From 0c54d91dd1d33235ae97566600e692edfb613642 Mon Sep 17 00:00:00 2001
From: f321x <[email protected]>
Date: Thu, 10 Jul 2025 17:45:20 +0200
Subject: [PATCH] make docker build reproducible
attempts to make the docker build more reproducible by:
* pinning the docker image (alpine:3.21) to a hash
* version pinning the apk packages in the dockerfile
* setting TZ, LC_ALL and SOURCE_DATE_EPOCH in the container
* only building single threaded (make -j1)
* use a fixed build directory in `build-runtime.sh` instead of mktemp
* prevent linker from adding build id (-Wl,--build-id=none)
* replace absolute build paths in debug info with relative paths
(-fdebug-prefix-map=$(PWD)=.)
* replace absolute paths in all compiler output with relative paths
(-ffile-prefix-map=$(PWD)=.)
* stop adding gnu-debuglink to runtime binary
---
scripts/build-runtime.sh | 18 +++++++++++----
scripts/common/install-dependencies.sh | 2 +-
scripts/docker/Dockerfile | 32 ++++++++++++++++++++++----
src/runtime/Makefile | 2 +-
4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/scripts/build-runtime.sh b/scripts/build-runtime.sh
index 3ce3b91..e11f082 100755
--- a/scripts/build-runtime.sh
+++ b/scripts/build-runtime.sh
@@ -8,8 +8,10 @@ set -euo pipefail
out_dir="$(readlink -f "$(pwd)")"/out
mkdir -p "$out_dir"
-# we create a temporary build directory
-build_dir="$(mktemp -d -t type2-runtime-build-XXXXXX)"
+# we create a temporary build directory with a fixed name for reproducibility
+build_dir="$(readlink -f "$(pwd)")"/build-runtime-temp
+rm -rf "$build_dir"
+mkdir -p "$build_dir"
# since the plain ol' Makefile doesn't support out-of-source builds at all, we need to copy all the files
cp -R src "$build_dir"/
@@ -17,13 +19,14 @@ cp -R src "$build_dir"/
pushd "$build_dir"
pushd src/runtime/
-make -j"$(nproc)" runtime
+make -j1 runtime
file runtime
objcopy --only-keep-debug runtime runtime.debug
-strip --strip-debug --strip-unneeded runtime
+# strip --strip-debug --strip-unneeded runtime
+strip --strip-all runtime
ls -lh runtime runtime.debug
@@ -50,7 +53,7 @@ fi
mv runtime runtime-"$architecture"
mv runtime.debug runtime-"$architecture".debug
-objcopy --add-gnu-debuglink runtime-"$architecture".debug runtime-"$architecture"
+# objcopy --add-gnu-debuglink runtime-"$architecture".debug runtime-"$architecture"
# "classic" magic bytes which cannot be embedded with compiler magic, always do AFTER strip
# needs to be done after calls to objcopy, strip etc.
@@ -61,3 +64,8 @@ cp runtime-"$architecture" "$out_dir"/
cp runtime-"$architecture".debug "$out_dir"/
ls -al "$out_dir"
+
+# cleanup
+popd # return to build_dir
+popd # return to original working directory
+rm -rf "$build_dir"
diff --git a/scripts/common/install-dependencies.sh b/scripts/common/install-dependencies.sh
index 0e21cdb..5237079 100755
--- a/scripts/common/install-dependencies.sh
+++ b/scripts/common/install-dependencies.sh
@@ -39,7 +39,7 @@ tar xf 0.5.2.tar.gz
pushd squashfuse-*/
./autogen.sh
./configure LDFLAGS="-static"
-make -j"$(nproc)"
+make -j1
make install
/usr/bin/install -c -m 644 ./*.h '/usr/local/include/squashfuse'
popd
diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile
index 07b6533..fba9c6e 100644
--- a/scripts/docker/Dockerfile
+++ b/scripts/docker/Dockerfile
@@ -1,13 +1,35 @@
-FROM alpine:3.21
+FROM alpine:3.21@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
# includes dependencies from https://git.alpinelinux.org/aports/tree/main/fuse3/APKBUILD
RUN apk add --no-cache \
- bash alpine-sdk util-linux strace file autoconf automake libtool xz \
- eudev-dev gettext-dev linux-headers meson \
- zstd-dev zstd-static zlib-dev zlib-static clang musl-dev mimalloc-dev
+ bash=5.2.37-r0 \
+ alpine-sdk=1.1-r0 \
+ util-linux=2.40.4-r1 \
+ strace=6.12-r0 \
+ file=5.46-r2 \
+ autoconf=2.72-r0 \
+ automake=1.17-r0 \
+ libtool=2.4.7-r3 \
+ xz=5.6.3-r1 \
+ eudev-dev=3.2.14-r5 \
+ gettext-dev=0.22.5-r0 \
+ linux-headers=6.6-r1 \
+ meson=1.6.1-r0 \
+ zstd-dev=1.5.6-r2 \
+ zstd-static=1.5.6-r2 \
+ zlib-dev=1.3.1-r2 \
+ zlib-static=1.3.1-r2 \
+ clang19=19.1.4-r0 \
+ musl-dev=1.2.5-r9 \
+ mimalloc2-dev=2.1.7-r0
COPY scripts/common/install-dependencies.sh /tmp/scripts/common/install-dependencies.sh
COPY patches/ /tmp/patches/
+# Set environment variables for reproducible build
+ENV SOURCE_DATE_EPOCH=1640995200
+ENV TZ=UTC
+ENV LC_ALL=C
+
WORKDIR /tmp
-RUN bash scripts/common/install-dependencies.sh
+RUN bash scripts/common/install-dependencies.sh
\ No newline at end of file
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index 9fd4165..3a3cbaa 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -1,6 +1,6 @@
GIT_COMMIT := $(shell cat version)
CC = clang
-CFLAGS = -std=gnu99 -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\"$(GIT_COMMIT)\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -static -Wall -Werror -static-pie
+CFLAGS = -std=gnu99 -Os -D_FILE_OFFSET_BITS=64 -DGIT_COMMIT=\"$(GIT_COMMIT)\" -T data_sections.ld -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--build-id=none -static -Wall -Werror -static-pie -fdebug-prefix-map=$(PWD)=. -ffile-prefix-map=$(PWD)=.
LIBS = -lsquashfuse -lsquashfuse_ll -lzstd -lz -lfuse3 -lmimalloc
all: runtime
--
2.50.0
- 主要语言
- C
- 星标
- 73
- 派生
- 38
- 平均合并
- 3 小时 31 分钟
- 30 天内合并 PR
- 1
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
AppImage/type2-runtime 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 48/100
AppImage/type2-runtime#153 ·
-
fusermount3 get's skipped if not setuid, which breaks new fuse implementations可能已有人在做 @probonopd 于 16 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 68/100
AppImage/type2-runtime#150 · 4 条评论 ·
-
Some apps can break unless it is run extracted可能已有人在做 @probonopd 于 4 天前认领。 未关闭bug
难度 4/5 3-5 天 新手友好度 35/100
AppImage/type2-runtime#144 · 2 条评论 ·
-
Tagged Releases未关闭
难度 4/5 3-5 天 新手友好度 25/100
AppImage/type2-runtime#140 · 17 条评论 · 3 个 reaction ·
-
Consider adding support for FreeBSD可能已有人在做 @neilpang 于 69 天前认领。 未关闭
难度 5/5 一周以上 新手友好度 28/100
AppImage/type2-runtime#126 · 4 条评论 ·
查看 AppImage/type2-runtime 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 74/100
EchoTools/nevr-runtime#117 · 2 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 67/100
DarkFlippers/qUnleashed#240 ·
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 84/100
AFLplusplus/AFLplusplus#2899 ·
-
难度 2/5 1-3 小时 新手友好度 78/100
HarbourMasters/Shipwright#7320 ·
维护者通常 1 天内回复