From 2e296cae929a4b08f7f288049d938721971d3c96 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 11:38:27 +0330 Subject: [PATCH 01/11] fix: make syslinux download resilient (try multiple locations) --- Dockerfile | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index e78721b..cd2e833 100644 --- a/Dockerfile +++ b/Dockerfile @@ -95,13 +95,25 @@ RUN --mount=type=cache,target=/build/cache \ # Download and extract Syslinux # Note: Using alternative download locations due to mirror availability WORKDIR /build/sources -RUN curl -fsSL -o syslinux.tar.gz \ - "https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz" || \ - curl -fsSL -o syslinux.tar.gz \ - "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz" && \ - tar xzf syslinux.tar.gz && \ - rm syslinux.tar.gz && \ - mv syslinux-* syslinux +RUN set -eux; \ + tried=0; \ + for url in \ + "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ + "https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ + "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/Testing/${SYSLINUX_VERSION}/syslinux-${SYSLINUX_VERSION}.tar.gz"; do \ + echo "Trying $url"; \ + if curl -fsSL -o syslinux.tar.gz "$url"; then \ + tried=1; \ + break; \ + else \ + echo "Failed to download from $url"; \ + fi; \ + done; \ + if [ "$tried" -ne 1 ]; then \ + echo "ERROR: Unable to download syslinux ${SYSLINUX_VERSION}" >&2; \ + exit 22; \ + fi; \ + tar xzf syslinux.tar.gz && rm syslinux.tar.gz && mv "syslinux-${SYSLINUX_VERSION}" syslinux # ----------------------------------------------------------------------------- # Stage 3: Build Linux kernel From 9b615e43f8ab3b29d94f94025132e1488aec1f22 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 11:43:49 +0330 Subject: [PATCH 02/11] Refactor script directory variable assignments --- scripts/clean.sh | 6 ++++-- scripts/test.sh | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/clean.sh b/scripts/clean.sh index 3139ecc..9dee821 100755 --- a/scripts/clean.sh +++ b/scripts/clean.sh @@ -6,8 +6,10 @@ set -euo pipefail -readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -readonly PROJECT_DIR="$(dirname "${SCRIPT_DIR}")" +readonly SCRIPT_DIR +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly PROJECT_DIR +PROJECT_DIR="$(dirname "${SCRIPT_DIR}")" readonly GREEN='\033[0;32m' readonly BLUE='\033[0;34m' diff --git a/scripts/test.sh b/scripts/test.sh index 3bad83c..84acead 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -6,8 +6,10 @@ set -euo pipefail -readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -readonly PROJECT_DIR="$(dirname "${SCRIPT_DIR}")" +readonly SCRIPT_DIR +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly PROJECT_DIR +PROJECT_DIR="$(dirname "${SCRIPT_DIR}")" readonly GREEN='\033[0;32m' readonly RED='\033[0;31m' From 694a79f09a428a3779bef3fa958318a47750530a Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 11:50:21 +0330 Subject: [PATCH 03/11] fix: make BusyBox build non-interactive and remove invalid BUILD_JOBS default in Dockerfile --- Dockerfile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index cd2e833..e5ce169 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ ARG LINUX_VERSION=master ARG BUSYBOX_VERSION=master ARG SYSLINUX_VERSION=6.04-pre1 ARG DEBIAN_FRONTEND=noninteractive -ARG BUILD_JOBS=auto +ARG BUILD_JOBS= # Add metadata labels LABEL maintainer="handbuilt-linux-project" @@ -149,7 +149,11 @@ COPY busybox.config /build/busybox/.config # Build and install BusyBox WORKDIR /build/busybox -RUN make oldconfig && \ +RUN if [ -f .config ]; then \ + make olddefconfig; \ + else \ + make defconfig; \ + fi && \ make -j"${BUILD_JOBS:-$(nproc)}" && \ make CONFIG_PREFIX=/build/initramfs install && \ strip /build/initramfs/bin/busybox From cc21f9bec925863961f78a31f0580cac02a6848d Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 11:57:26 +0330 Subject: [PATCH 04/11] fix: fallback to make defconfig if olddefconfig target is missing in BusyBox build --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e5ce169..81f9d0f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -150,7 +150,7 @@ COPY busybox.config /build/busybox/.config # Build and install BusyBox WORKDIR /build/busybox RUN if [ -f .config ]; then \ - make olddefconfig; \ + make olddefconfig || make defconfig; \ else \ make defconfig; \ fi && \ From 096c3c83f1b72a7afcc96fb9ed904ac5c30a0c37 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:01:21 +0330 Subject: [PATCH 05/11] Update BusyBox build process in Dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 81f9d0f..7c38791 100644 --- a/Dockerfile +++ b/Dockerfile @@ -149,8 +149,8 @@ COPY busybox.config /build/busybox/.config # Build and install BusyBox WORKDIR /build/busybox -RUN if [ -f .config ]; then \ - make olddefconfig || make defconfig; \ +RUN if make olddefconfig; then \ + echo "Used olddefconfig"; \ else \ make defconfig; \ fi && \ From d66415569215398c7459ca2655527b46f8fbdd15 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:12:09 +0330 Subject: [PATCH 06/11] Update Syslinux version and improve build scripts --- Dockerfile | 103 +++++++++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 67 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7c38791..0caf943 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,31 +2,20 @@ # ============================================================================= # Multi-stage Dockerfile for Building Custom Linux Distribution # ============================================================================= -# This Dockerfile builds a minimal Linux distribution from scratch using: -# - Linux Kernel (from torvalds/linux) -# - BusyBox (minimal userspace utilities) -# - Syslinux (bootloader) -# ============================================================================= -# ----------------------------------------------------------------------------- -# Stage 1: Base builder with build dependencies -# ----------------------------------------------------------------------------- FROM debian:sid-slim AS builder-base -# Set build arguments for versioning and configuration ARG LINUX_VERSION=master ARG BUSYBOX_VERSION=master -ARG SYSLINUX_VERSION=6.04-pre1 +ARG SYSLINUX_VERSION=6.03 ARG DEBIAN_FRONTEND=noninteractive ARG BUILD_JOBS= -# Add metadata labels LABEL maintainer="handbuilt-linux-project" LABEL description="Custom Linux distribution builder" LABEL version="1.0.0" -# Install build dependencies in a single layer with cleanup -# hadolint ignore=DL3008 +# Install build dependencies RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ @@ -53,11 +42,10 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# Set working directory WORKDIR /build # ----------------------------------------------------------------------------- -# Stage 2: Download and prepare sources +# Stage: source-downloader # ----------------------------------------------------------------------------- FROM builder-base AS source-downloader @@ -65,35 +53,35 @@ ARG LINUX_VERSION=master ARG BUSYBOX_VERSION=master ARG SYSLINUX_VERSION=6.03 -# Create directory structure RUN mkdir -p /build/initramfs && \ mkdir -p /build/myiso/isolinux && \ - mkdir -p /build/sources + mkdir -p /build/sources && \ + mkdir -p /build/cache -# Download Linux kernel source WORKDIR /build/sources + +# Clone Linux (shallow, branch/tag from ARG) RUN --mount=type=cache,target=/build/cache \ - if [ ! -f /build/cache/linux/.git/config ]; then \ - git clone --depth 1 \ - https://github.com/torvalds/linux.git linux && \ + if [ ! -d /build/cache/linux ]; then \ + git clone --depth 1 --branch "${LINUX_VERSION}" https://github.com/torvalds/linux.git linux || \ + git clone --depth 1 https://github.com/torvalds/linux.git linux; \ cp -r linux /build/cache/linux; \ else \ cp -r /build/cache/linux linux; \ fi -# Download BusyBox source +# Clone BusyBox (shallow, branch/tag from ARG) WORKDIR /build/sources RUN --mount=type=cache,target=/build/cache \ - if [ ! -f /build/cache/busybox/.git/config ]; then \ - git clone --depth 1 \ - https://git.busybox.net/busybox busybox && \ + if [ ! -d /build/cache/busybox ]; then \ + git clone --depth 1 --branch "${BUSYBOX_VERSION}" https://git.busybox.net/busybox busybox || \ + git clone --depth 1 https://git.busybox.net/busybox busybox; \ cp -r busybox /build/cache/busybox; \ else \ cp -r /build/cache/busybox busybox; \ fi -# Download and extract Syslinux -# Note: Using alternative download locations due to mirror availability +# Download and extract Syslinux (tries multiple URLs) WORKDIR /build/sources RUN set -eux; \ tried=0; \ @@ -116,88 +104,79 @@ RUN set -eux; \ tar xzf syslinux.tar.gz && rm syslinux.tar.gz && mv "syslinux-${SYSLINUX_VERSION}" syslinux # ----------------------------------------------------------------------------- -# Stage 3: Build Linux kernel +# Stage: kernel-builder # ----------------------------------------------------------------------------- FROM builder-base AS kernel-builder ARG BUILD_JOBS +ARG LINUX_VERSION=master -# Copy kernel source from downloader stage COPY --from=source-downloader /build/sources/linux /build/linux - -# Copy kernel configuration +# If you have a linux.config in repo, it will be copied by the build context COPY linux.config /build/linux/.config -# Build kernel WORKDIR /build/linux RUN make olddefconfig && \ make -j"${BUILD_JOBS:-$(nproc)}" && \ (strip --strip-debug arch/x86/boot/bzImage 2>/dev/null || true) # ----------------------------------------------------------------------------- -# Stage 4: Build BusyBox +# Stage: busybox-builder # ----------------------------------------------------------------------------- FROM builder-base AS busybox-builder ARG BUILD_JOBS +ARG BUSYBOX_VERSION=master -# Copy BusyBox source from downloader stage COPY --from=source-downloader /build/sources/busybox /build/busybox - -# Copy BusyBox configuration COPY busybox.config /build/busybox/.config -# Build and install BusyBox WORKDIR /build/busybox -RUN if make olddefconfig; then \ - echo "Used olddefconfig"; \ + +# Use a robust config step: +# - If a .config exists, prefer to run oldconfig (accept defaults automatically) +# - If oldconfig isn't available or fails, fall back to defconfig +RUN if [ -f .config ]; then \ + # Try non-interactive oldconfig (accept defaults); if not supported/fails, fall back + (yes "" | make oldconfig) || make defconfig; \ else \ make defconfig; \ fi && \ make -j"${BUILD_JOBS:-$(nproc)}" && \ make CONFIG_PREFIX=/build/initramfs install && \ - strip /build/initramfs/bin/busybox + strip /build/initramfs/bin/busybox || true # ----------------------------------------------------------------------------- -# Stage 5: Create initramfs +# Stage: initramfs-builder # ----------------------------------------------------------------------------- FROM builder-base AS initramfs-builder -# Copy BusyBox installation COPY --from=busybox-builder /build/initramfs /build/initramfs - -# Copy init script and make it executable COPY init.sh /build/initramfs/init + RUN chmod +x /build/initramfs/init -# Create initramfs archive WORKDIR /build/initramfs SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN find . -print0 | cpio --null --create --format=newc | gzip -9 > /build/initramfs.cpio.gz # ----------------------------------------------------------------------------- -# Stage 6: Create bootable ISO +# Stage: iso-builder # ----------------------------------------------------------------------------- FROM builder-base AS iso-builder -# Copy syslinux files -COPY --from=source-downloader /build/sources/syslinux /build/syslinux +ARG SYSLINUX_VERSION=6.03 -# Copy kernel +COPY --from=source-downloader /build/sources/syslinux /build/syslinux COPY --from=kernel-builder /build/linux/arch/x86/boot/bzImage /build/myiso/bzImage - -# Copy initramfs COPY --from=initramfs-builder /build/initramfs.cpio.gz /build/myiso/initramfs -# Copy syslinux bootloader files WORKDIR /build RUN cp /build/syslinux/bios/core/isolinux.bin /build/myiso/isolinux/ && \ cp /build/syslinux/bios/com32/elflink/ldlinux/ldlinux.c32 /build/myiso/isolinux/ -# Copy bootloader configuration COPY syslinux.cfg /build/myiso/isolinux/isolinux.cfg -# Create bootable ISO WORKDIR /build RUN mkisofs \ -J \ @@ -211,21 +190,19 @@ RUN mkisofs \ myiso # ----------------------------------------------------------------------------- -# Stage 7: Final minimal image with artifacts +# Stage: export-stage # ----------------------------------------------------------------------------- FROM scratch AS export-stage -# Copy build artifacts COPY --from=iso-builder /build/output.iso /output.iso COPY --from=kernel-builder /build/linux/arch/x86/boot/bzImage /bzImage COPY --from=initramfs-builder /build/initramfs.cpio.gz /initramfs # ----------------------------------------------------------------------------- -# Stage 8: Runtime image (default) +# Stage: runtime # ----------------------------------------------------------------------------- FROM debian:sid-slim AS runtime -# Install only runtime dependencies RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ @@ -235,32 +212,24 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# Create non-root user for better security RUN groupadd -r distro && \ useradd -r -g distro -d /distro -s /bin/bash distro && \ mkdir -p /distro && \ chown -R distro:distro /distro -# Copy build artifacts from iso-builder stage COPY --from=iso-builder /build/output.iso /distro/output.iso COPY --from=kernel-builder /build/linux/arch/x86/boot/bzImage /distro/bzImage COPY --from=initramfs-builder /build/initramfs.cpio.gz /distro/initramfs -# Copy scripts COPY --chown=distro:distro build.sh /distro/build.sh RUN chmod +x /distro/build.sh -# Set working directory and user WORKDIR /distro USER distro - -# Set environment variables ENV DISTRO_HOME=/distro ENV PATH="${DISTRO_HOME}:${PATH}" -# Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD [ -f "/distro/output.iso" ] || exit 1 -# Default command -CMD ["/bin/bash"] +CMD ["/bin/bash"] \ No newline at end of file From 557c9c5074adc0f1f0706f91efd8767896a907d1 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:15:23 +0330 Subject: [PATCH 07/11] Refactor Dockerfile for better readability and formatting --- Dockerfile | 88 +++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0caf943..1635a10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,25 +20,25 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -yq --no-install-recommends \ - build-essential \ - bzip2 \ - git \ - make \ - gcc \ - libncurses-dev \ - flex \ - bison \ - bc \ - cpio \ - libelf-dev \ - libssl-dev \ - syslinux-common \ - dosfstools \ - genisoimage \ - wget \ - curl \ - ca-certificates \ - xz-utils && \ + build-essential \ + bzip2 \ + git \ + make \ + gcc \ + libncurses-dev \ + flex \ + bison \ + bc \ + cpio \ + libelf-dev \ + libssl-dev \ + syslinux-common \ + dosfstools \ + genisoimage \ + wget \ + curl \ + ca-certificates \ + xz-utils && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* @@ -63,22 +63,22 @@ WORKDIR /build/sources # Clone Linux (shallow, branch/tag from ARG) RUN --mount=type=cache,target=/build/cache \ if [ ! -d /build/cache/linux ]; then \ - git clone --depth 1 --branch "${LINUX_VERSION}" https://github.com/torvalds/linux.git linux || \ - git clone --depth 1 https://github.com/torvalds/linux.git linux; \ - cp -r linux /build/cache/linux; \ + git clone --depth 1 --branch "${LINUX_VERSION}" https://github.com/torvalds/linux.git linux || \ + git clone --depth 1 https://github.com/torvalds/linux.git linux; \ + cp -r linux /build/cache/linux; \ else \ - cp -r /build/cache/linux linux; \ + cp -r /build/cache/linux linux; \ fi # Clone BusyBox (shallow, branch/tag from ARG) WORKDIR /build/sources RUN --mount=type=cache,target=/build/cache \ if [ ! -d /build/cache/busybox ]; then \ - git clone --depth 1 --branch "${BUSYBOX_VERSION}" https://git.busybox.net/busybox busybox || \ - git clone --depth 1 https://git.busybox.net/busybox busybox; \ - cp -r busybox /build/cache/busybox; \ + git clone --depth 1 --branch "${BUSYBOX_VERSION}" https://git.busybox.net/busybox busybox || \ + git clone --depth 1 https://git.busybox.net/busybox busybox; \ + cp -r busybox /build/cache/busybox; \ else \ - cp -r /build/cache/busybox busybox; \ + cp -r /build/cache/busybox busybox; \ fi # Download and extract Syslinux (tries multiple URLs) @@ -86,20 +86,20 @@ WORKDIR /build/sources RUN set -eux; \ tried=0; \ for url in \ - "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ - "https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ - "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/Testing/${SYSLINUX_VERSION}/syslinux-${SYSLINUX_VERSION}.tar.gz"; do \ - echo "Trying $url"; \ - if curl -fsSL -o syslinux.tar.gz "$url"; then \ - tried=1; \ - break; \ - else \ - echo "Failed to download from $url"; \ - fi; \ + "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ + "https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz" \ + "https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/Testing/${SYSLINUX_VERSION}/syslinux-${SYSLINUX_VERSION}.tar.gz"; do \ + echo "Trying $url"; \ + if curl -fsSL -o syslinux.tar.gz "$url"; then \ + tried=1; \ + break; \ + else \ + echo "Failed to download from $url"; \ + fi; \ done; \ if [ "$tried" -ne 1 ]; then \ - echo "ERROR: Unable to download syslinux ${SYSLINUX_VERSION}" >&2; \ - exit 22; \ + echo "ERROR: Unable to download syslinux ${SYSLINUX_VERSION}" >&2; \ + exit 22; \ fi; \ tar xzf syslinux.tar.gz && rm syslinux.tar.gz && mv "syslinux-${SYSLINUX_VERSION}" syslinux @@ -137,10 +137,10 @@ WORKDIR /build/busybox # - If a .config exists, prefer to run oldconfig (accept defaults automatically) # - If oldconfig isn't available or fails, fall back to defconfig RUN if [ -f .config ]; then \ - # Try non-interactive oldconfig (accept defaults); if not supported/fails, fall back - (yes "" | make oldconfig) || make defconfig; \ + # Try non-interactive oldconfig (accept defaults); if not supported/fails, fall back + (yes "" | make oldconfig) || make defconfig; \ else \ - make defconfig; \ + make defconfig; \ fi && \ make -j"${BUILD_JOBS:-$(nproc)}" && \ make CONFIG_PREFIX=/build/initramfs install && \ @@ -207,8 +207,8 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ apt-get install -yq --no-install-recommends \ - qemu-system-x86 \ - qemu-utils && \ + qemu-system-x86 \ + qemu-utils && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* From 9bb3ec6fb150ed0391244d9d42f3e6a3c7e6430b Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:19:35 +0330 Subject: [PATCH 08/11] Set bash as the shell with pipefail option in Dockerfile --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1635a10..9418268 100644 --- a/Dockerfile +++ b/Dockerfile @@ -136,9 +136,10 @@ WORKDIR /build/busybox # Use a robust config step: # - If a .config exists, prefer to run oldconfig (accept defaults automatically) # - If oldconfig isn't available or fails, fall back to defconfig +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN if [ -f .config ]; then \ # Try non-interactive oldconfig (accept defaults); if not supported/fails, fall back - (yes "" | make oldconfig) || make defconfig; \ + if ! (yes "" | make oldconfig); then make defconfig; fi; \ else \ make defconfig; \ fi && \ From 4159439fb90961027fa67cd882a6d8d52602ab13 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:22:08 +0330 Subject: [PATCH 09/11] fix dockerfile syntax --- Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9418268..c5889df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -138,10 +138,11 @@ WORKDIR /build/busybox # - If oldconfig isn't available or fails, fall back to defconfig SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN if [ -f .config ]; then \ - # Try non-interactive oldconfig (accept defaults); if not supported/fails, fall back - if ! (yes "" | make oldconfig); then make defconfig; fi; \ + if ! (yes "" | make oldconfig); then \ + make defconfig; \ + fi; \ else \ - make defconfig; \ + make defconfig; \ fi && \ make -j"${BUILD_JOBS:-$(nproc)}" && \ make CONFIG_PREFIX=/build/initramfs install && \ From dd7cb595fa7edf7b46ba501c13ca102b1acadef1 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:36:46 +0330 Subject: [PATCH 10/11] Improve busybox build and installation process --- Dockerfile | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index c5889df..44a9d2d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -137,25 +137,44 @@ WORKDIR /build/busybox # - If a .config exists, prefer to run oldconfig (accept defaults automatically) # - If oldconfig isn't available or fails, fall back to defconfig SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN if [ -f .config ]; then \ - if ! (yes "" | make oldconfig); then \ - make defconfig; \ - fi; \ - else \ - make defconfig; \ - fi && \ - make -j"${BUILD_JOBS:-$(nproc)}" && \ - make CONFIG_PREFIX=/build/initramfs install && \ - strip /build/initramfs/bin/busybox || true +RUN set -eux; \ + mkdir -p /build/initramfs; \ + # prefer existing .config, accept defaults non-interactively if present + if [ -f .config ]; then \ + if ! yes "" | make oldconfig; then \ + make defconfig; \ + fi; \ + else \ + make defconfig; \ + fi; \ + # build + make -j"${BUILD_JOBS:-$(nproc)}"; \ + # install into explicit path + make CONFIG_PREFIX=/build/initramfs install; \ + # sanity checks — fail early with diagnostics if artifacts missing + if [ ! -x /build/initramfs/bin/busybox ]; then \ + echo "ERROR: busybox install did not produce /build/initramfs/bin/busybox"; \ + echo "workspace /build contents:"; ls -la /build || true; \ + echo "busybox tree:"; ls -la /build/initramfs || true; \ + exit 1; \ + fi; \ + # shrink binary if possible (non-fatal) + strip --strip-all /build/initramfs/bin/busybox || true; \ + # make a tarball artifact to make COPY from BuildKit more robust + tar -C /build -czf /build/initramfs.tar.gz initramfs # ----------------------------------------------------------------------------- # Stage: initramfs-builder # ----------------------------------------------------------------------------- FROM builder-base AS initramfs-builder -COPY --from=busybox-builder /build/initramfs /build/initramfs -COPY init.sh /build/initramfs/init +# Copy the tarball artifact from busybox-builder and extract it atomically +COPY --from=busybox-builder /build/initramfs.tar.gz /build/initramfs.tar.gz +RUN set -eux; \ + tar -C /build -xzf /build/initramfs.tar.gz && rm /build/initramfs.tar.gz +# Add the init script into the extracted initramfs and make executable +COPY init.sh /build/initramfs/init RUN chmod +x /build/initramfs/init WORKDIR /build/initramfs From b2ccec9cb3bb710ab3780d9709e2a1a37e7bfd21 Mon Sep 17 00:00:00 2001 From: ehsanghaffarii Date: Thu, 20 Nov 2025 12:40:05 +0330 Subject: [PATCH 11/11] Refactor Dockerfile for robust build and artifact creation --- Dockerfile | 62 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/Dockerfile b/Dockerfile index 44a9d2d..4e14133 100644 --- a/Dockerfile +++ b/Dockerfile @@ -133,47 +133,49 @@ COPY busybox.config /build/busybox/.config WORKDIR /build/busybox -# Use a robust config step: -# - If a .config exists, prefer to run oldconfig (accept defaults automatically) -# - If oldconfig isn't available or fails, fall back to defconfig +# Use a robust config, build, install; create an explicit tarball artifact and verify it SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN set -eux; \ - mkdir -p /build/initramfs; \ - # prefer existing .config, accept defaults non-interactively if present - if [ -f .config ]; then \ - if ! yes "" | make oldconfig; then \ - make defconfig; \ - fi; \ - else \ - make defconfig; \ - fi; \ - # build - make -j"${BUILD_JOBS:-$(nproc)}"; \ - # install into explicit path - make CONFIG_PREFIX=/build/initramfs install; \ - # sanity checks — fail early with diagnostics if artifacts missing - if [ ! -x /build/initramfs/bin/busybox ]; then \ - echo "ERROR: busybox install did not produce /build/initramfs/bin/busybox"; \ - echo "workspace /build contents:"; ls -la /build || true; \ - echo "busybox tree:"; ls -la /build/initramfs || true; \ - exit 1; \ - fi; \ - # shrink binary if possible (non-fatal) - strip --strip-all /build/initramfs/bin/busybox || true; \ - # make a tarball artifact to make COPY from BuildKit more robust - tar -C /build -czf /build/initramfs.tar.gz initramfs + mkdir -p /build/initramfs; \ + # configure (prefer existing .config, accept defaults non-interactively) + if [ -f .config ]; then \ + if ! yes "" | make oldconfig; then \ + make defconfig; \ + fi; \ + else \ + make defconfig; \ + fi; \ + # build + make -j"${BUILD_JOBS:-$(nproc)}"; \ + # install into explicit path + make CONFIG_PREFIX=/build/initramfs install; \ + # sanity checks — fail early with diagnostics if artifacts missing + if [ ! -x /build/initramfs/bin/busybox ]; then \ + echo "ERROR: busybox install did not produce /build/initramfs/bin/busybox"; \ + echo "workspace /build contents:"; ls -la /build || true; \ + echo "busybox tree:"; ls -la /build/initramfs || true; \ + exit 1; \ + fi; \ + # shrink binary if possible (non-fatal) + strip --strip-all /build/initramfs/bin/busybox || true; \ + # create a single tarball artifact for reliable COPY by BuildKit + tar -C /build -czf /build/initramfs.tar.gz initramfs; \ + ls -la /build/initramfs.tar.gz # ----------------------------------------------------------------------------- # Stage: initramfs-builder # ----------------------------------------------------------------------------- FROM builder-base AS initramfs-builder -# Copy the tarball artifact from busybox-builder and extract it atomically +# Copy the tarball artifact and extract it, then add/overwrite init COPY --from=busybox-builder /build/initramfs.tar.gz /build/initramfs.tar.gz + +WORKDIR /build RUN set -eux; \ - tar -C /build -xzf /build/initramfs.tar.gz && rm /build/initramfs.tar.gz + mkdir -p /build; \ + tar -C /build -xzf /build/initramfs.tar.gz && rm /build/initramfs.tar.gz; \ + ls -la /build/initramfs -# Add the init script into the extracted initramfs and make executable COPY init.sh /build/initramfs/init RUN chmod +x /build/initramfs/init