Files
zosbuilder/docs/BUILD.md

9.5 KiB

Alpine Zero-OS Build Process

Complete build system documentation for the Alpine-based Zero-OS initramfs.

Build Environment - Dockerfile.alpine

# Alpine-based Zero-OS Initramfs Builder
FROM alpine:3.22

# Set build arguments
ARG TARGETARCH=amd64
ARG BUILDMODE=debug

# Set environment variables
ENV BUILDMODE=${BUILDMODE}
ENV TARGETARCH=${TARGETARCH}

# Install build dependencies
RUN apk add --no-cache \
    # Build tools
    build-base \
    linux-headers \
    cmake \
    git \
    wget \
    curl \
    cpio \
    xz \
    gzip \
    bc \
    perl \
    python3 \
    # Kernel build dependencies
    linux-lts-dev \
    linux-lts \
    elfutils-dev \
    openssl-dev \
    # Archive tools
    tar \
    bzip2 \
    # Text processing
    sed \
    grep \
    findutils

# Create directories
RUN mkdir -p /build/initramfs /build/kernel /build/output /build/github

# Set working directory
WORKDIR /build

# Copy build scripts
COPY scripts/ /build/scripts/
COPY configs/ /build/configs/

# Make scripts executable
RUN chmod +x /build/scripts/*.sh

# Default command
CMD ["/build/scripts/build-initramfs.sh"]

Docker Compose Configuration

services:
  builder:
    build:
      context: ..
      dockerfile: build/Dockerfile.alpine
      args:
        BUILDMODE: "${BUILDMODE:-debug}"
        TARGETARCH: "${TARGETARCH:-amd64}"
    image: zero-os-alpine-builder:latest
    container_name: zero-os-alpine-builder
    privileged: true
    volumes:
      # Mount source configs and scripts
      - ../configs:/build/configs:ro
      - ../scripts:/build/scripts:ro
      # Mount output directory
      - ../output:/build/output
      # Cache directories for faster builds
      - github-cache:/build/github
      - kernel-cache:/build/kernel
    environment:
      - BUILDMODE=${BUILDMODE:-debug}
      - TARGETARCH=${TARGETARCH:-amd64}
    working_dir: /build

  # Quick shell access for debugging
  shell:
    extends: builder
    command: /bin/sh
    stdin_open: true
    tty: true

volumes:
  github-cache:
  kernel-cache:

Build Scripts

Main Build Script - build-initramfs.sh

#!/bin/sh
set -e

echo "====================================="
echo "=   Alpine Zero-OS Initramfs Build  ="
echo "====================================="
echo ""

# Source configuration
. /build/configs/build.conf

echo "[+] Build mode: $BUILDMODE"
echo "[+] Target arch: $TARGETARCH"
echo ""

# Phase 1: Install Alpine packages to initramfs
echo "[+] Installing Alpine packages..."
/build/scripts/install-packages.sh

# Phase 2: Fetch GitHub components
echo "[+] Fetching GitHub components..."
/build/scripts/fetch-github.sh

# Phase 3: Setup initramfs structure
echo "[+] Setting up initramfs structure..."
/build/scripts/setup-initramfs.sh

# Phase 4: Build kernel with embedded initramfs
echo "[+] Building kernel..."
/build/scripts/build-kernel.sh

echo ""
echo "[+] Build completed successfully!"
echo "[+] Output: /build/output/vmlinuz.efi"

Package Installation Script - install-packages.sh

#!/bin/sh
set -e

INITRAMFS_ROOT="/build/initramfs"
PACKAGES_FILE="/build/configs/packages.txt"

echo "[+] Creating initramfs root directory..."
mkdir -p "$INITRAMFS_ROOT"

echo "[+] Installing Alpine base system..."
apk add --root "$INITRAMFS_ROOT" --update-cache --initdb alpine-base

echo "[+] Installing Zero-OS packages..."
while read -r package; do
    # Skip comments and empty lines
    case "$package" in
        \#*|"") continue ;;
    esac
    
    echo "  Installing: $package"
    apk add --root "$INITRAMFS_ROOT" --no-cache "$package"
done < "$PACKAGES_FILE"

echo "[+] Setting up initramfs filesystem structure..."
# Create essential directories
mkdir -p "$INITRAMFS_ROOT"/{dev,proc,sys,mnt,tmp,var/run,var/log}

# Create device nodes (minimal set)
mknod "$INITRAMFS_ROOT/dev/console" c 5 1
mknod "$INITRAMFS_ROOT/dev/null" c 1 3
mknod "$INITRAMFS_ROOT/dev/zero" c 1 5

# Set proper permissions
chmod 666 "$INITRAMFS_ROOT/dev/null" "$INITRAMFS_ROOT/dev/zero"
chmod 600 "$INITRAMFS_ROOT/dev/console"

echo "[+] Alpine packages installed successfully"

GitHub Components Fetcher - fetch-github.sh

#!/bin/sh
set -e

GITHUB_DIR="/build/github"
INITRAMFS_ROOT="/build/initramfs"

echo "[+] Fetching GitHub components..."

# Create cache directory
mkdir -p "$GITHUB_DIR"

# Function to download latest release
download_github_release() {
    local repo="$1"
    local binary="$2"
    local install_path="$3"
    
    echo "  Fetching: $repo"
    
    # Get latest release URL
    local api_url="https://api.github.com/repos/$repo/releases/latest"
    local download_url=$(wget -qO- "$api_url" | grep "browser_download_url.*linux.*amd64" | cut -d '"' -f 4 | head -1)
    
    if [ -z "$download_url" ]; then
        echo "    Warning: No linux amd64 release found for $repo"
        return 1
    fi
    
    # Download and install
    local filename=$(basename "$download_url")
    wget -O "$GITHUB_DIR/$filename" "$download_url"
    
    # Extract if needed and install
    case "$filename" in
        *.tar.gz|*.tgz)
            tar -xzf "$GITHUB_DIR/$filename" -C "$GITHUB_DIR"
            cp "$GITHUB_DIR/$binary" "$INITRAMFS_ROOT$install_path"
            ;;
        *.zip)
            unzip -q "$GITHUB_DIR/$filename" -d "$GITHUB_DIR"
            cp "$GITHUB_DIR/$binary" "$INITRAMFS_ROOT$install_path"
            ;;
        *)
            # Assume it's a binary
            cp "$GITHUB_DIR/$filename" "$INITRAMFS_ROOT$install_path/$binary"
            ;;
    esac
    
    chmod +x "$INITRAMFS_ROOT$install_path/$binary"
    echo "    Installed: $install_path/$binary"
}

# Fetch required components
download_github_release "threefoldtech/zinit" "zinit" "/sbin"
download_github_release "threefoldtech/core-x" "core-x" "/usr/bin"
download_github_release "threefoldtech/seektime" "seektime" "/usr/bin"
download_github_release "threefoldtech/rfs" "rfs" "/usr/bin"

echo "[+] GitHub components fetched successfully"

Initramfs Setup Script - setup-initramfs.sh

#!/bin/sh
set -e

INITRAMFS_ROOT="/build/initramfs"
CONFIG_DIR="/build/configs"

echo "[+] Setting up initramfs structure..."

# Copy init script
echo "  Installing init script..."
cp "$CONFIG_DIR/init" "$INITRAMFS_ROOT/init"
chmod +x "$INITRAMFS_ROOT/init"

# Copy zinit configuration
echo "  Installing zinit configuration..."
mkdir -p "$INITRAMFS_ROOT/etc/zinit"
cp -r "$CONFIG_DIR/zinit/"* "$INITRAMFS_ROOT/etc/zinit/"

# Copy other configurations
echo "  Installing system configuration..."
# Copy any additional configs needed

# Set up symlinks (similar to current system)
cd "$INITRAMFS_ROOT"
ln -sf usr/lib lib || true
ln -sf usr/lib lib64 || true

# Create initramfs archive
echo "[+] Creating initramfs archive..."
cd "$INITRAMFS_ROOT"
find . | cpio -H newc -o | xz --check=crc32 --x86 --lzma2=dict=1MiB > /build/output/initramfs.cpio.xz

echo "[+] Initramfs created: /build/output/initramfs.cpio.xz"

Kernel Build Script - build-kernel.sh

#!/bin/sh
set -e

KERNEL_DIR="/build/kernel"
OUTPUT_DIR="/build/output"
CONFIG_DIR="/build/configs"

echo "[+] Building kernel with embedded initramfs..."

# Setup kernel source
echo "  Preparing kernel source..."
mkdir -p "$KERNEL_DIR"
cd "$KERNEL_DIR"

# Use Alpine's kernel source
cp -r /usr/src/linux-* ./linux || {
    echo "  Downloading kernel source..."
    # Fallback: download kernel source if not available
    KERNEL_VERSION=$(uname -r | sed 's/-.*$//')
    wget -O- "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz" | tar -xJ
    mv "linux-${KERNEL_VERSION}" linux
}

cd linux

# Copy kernel configuration
echo "  Configuring kernel..."
cp "$CONFIG_DIR/kernel-config" .config

# Set initramfs path
echo "  Setting initramfs path..."
sed -i "s|^CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=\"$OUTPUT_DIR/initramfs.cpio.xz\"|" .config

# Build kernel
echo "  Compiling kernel..."
make -j$(nproc) bzImage

# Copy output
echo "  Installing kernel..."
cp arch/x86/boot/bzImage "$OUTPUT_DIR/vmlinuz.efi"

echo "[+] Kernel build completed: $OUTPUT_DIR/vmlinuz.efi"

Configuration Files

packages.txt

# Core Alpine packages for Zero-OS initramfs
busybox
busybox-suid
alpine-base
openssl
ca-certificates
util-linux
util-linux-misc
e2fsprogs
btrfs-progs
parted
dnsmasq
nftables
iproute2
openssh
curl
restic
wireguard-tools
zlib
fuse
unionfs-fuse
smartmontools
dmidecode
netcat-openbsd
redis
haveged
ethtool
dhcpcd
tcpdump
xfsprogs
bcache-tools
keyutils
zstd
libaio
eudev
kmod
linux-firmware

build.conf

# Build configuration
BUILDMODE="${BUILDMODE:-debug}"
TARGETARCH="${TARGETARCH:-amd64}"

# GitHub repositories
ZINIT_REPO="threefoldtech/zinit"
COREX_REPO="threefoldtech/core-x"
SEEKTIME_REPO="threefoldtech/seektime"
RFS_REPO="threefoldtech/rfs"

# Paths
INITRAMFS_ROOT="/build/initramfs"
KERNEL_DIR="/build/kernel"
OUTPUT_DIR="/build/output"
CONFIG_DIR="/build/configs"

Usage

# Build with defaults (debug mode)
cd alpine-initramfs/build
docker compose build
docker compose run --rm builder

# Build release version
BUILDMODE=release docker compose run --rm builder

# Interactive shell for debugging
docker compose run --rm shell

# Output
ls ../output/
# vmlinuz.efi - bootable kernel with embedded initramfs
# initramfs.cpio.xz - standalone initramfs archive

This build system provides:

  • Fast builds (~5 minutes vs 60+ minutes)
  • Latest packages from Alpine repositories
  • Minimal complexity - only 4 GitHub components to fetch
  • Same functionality - identical init flow and services
  • Better maintenance - Alpine handles package updates