+
+
+
+
rest
ocaml
+
atom
xgboost
+
+
torch
ractive
node
gh
+
+
#
+
+
webstorm
+
swift
qdrant
sse
cdn
eslint
+
webpack
+
firebase
+
==
+
+
+
||
+
+
netlify
travis
php
+
+
helm
py
tls
+
+
fiber
+
+
+
atom
//
+
hack
scheme
+
+
...
+
+
+
+
redhat
matplotlib
+
sklearn
qdrant
%
+
+
termux
ionic
dns
+
rails
rubymine
webpack
&
//
+
+
vscode
+
+
terraform
+
Back to Blog
Installing Alpine Linux with Custom Kernel: Complete Build Guide
Alpine Linux Kernel Linux

Installing Alpine Linux with Custom Kernel: Complete Build Guide

Published May 26, 2025

Learn how to install Alpine Linux with a custom kernel build. Step-by-step guide covering kernel compilation, configuration, and installation with practical examples.

12 min read
0 views
Table of Contents

Installing Alpine Linux with Custom Kernel: Complete Build Guide

I’ll show you how to install Alpine Linux with your own custom kernel. This gives you complete control over what features get included and lets you optimize for your specific hardware.

Introduction

Building a custom kernel might sound scary, but it’s actually pretty straightforward once you know the steps. I’ve done this dozens of times for different projects, and it’s really useful when you need specific drivers or want to remove unnecessary features.

The main reason I build custom kernels is for embedded systems or servers where I need exact control over what’s running. Sometimes you need a driver that’s not included in the standard kernel, or you want to strip out everything unnecessary to save memory.

Why You Need This

  • Remove unnecessary drivers and features to save memory
  • Add specific hardware support not in standard kernel
  • Enable experimental features for testing
  • Optimize performance for your exact hardware

Prerequisites

You’ll need these things first:

  • A working Linux system for building (can be Alpine or another distro)
  • At least 4GB RAM and 10GB free disk space
  • Basic knowledge of kernel configuration
  • Understanding of your hardware requirements
  • Internet connection for downloading kernel sources

Step 1: Set Up Build Environment

Installing Build Tools

I’ll start by setting up all the tools we need to compile a kernel.

What we’re doing: Installing the compiler toolchain and kernel build dependencies.

# Update package lists first
sudo apk update

# Install essential build tools
sudo apk add build-base linux-headers ncurses-dev

# Install kernel build dependencies
sudo apk add bc elfutils-dev openssl-dev

Code explanation:

  • build-base: Provides GCC compiler and essential build tools
  • linux-headers: Headers needed for kernel compilation
  • ncurses-dev: Library for kernel configuration menu interface
  • bc: Calculator used during kernel build process
  • elfutils-dev: Tools for handling ELF binary files
  • openssl-dev: SSL support for kernel signing

Expected Output:

(1/15) Installing binutils (2.40-r7)
(2/15) Installing gcc (12.2.1_git20220924-r10)
OK: 347 MiB in 87 packages

Creating Build Directory

What we’re doing: Setting up a dedicated workspace for kernel compilation.

# Create build directory
mkdir -p ~/kernel-build
cd ~/kernel-build

# Set up environment variables
export KBUILD_OUTPUT=$PWD/build
export ARCH=x86_64

Code explanation:

  • mkdir -p ~/kernel-build: Creates directory structure if it doesn’t exist
  • KBUILD_OUTPUT: Tells kernel build system where to put compiled files
  • ARCH=x86_64: Sets target architecture for compilation

Step 2: Download Kernel Source

Getting Kernel Source

What we’re doing: Downloading the Linux kernel source code from official repository.

# Download latest stable kernel
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.30.tar.xz

# Extract the source
tar -xf linux-6.6.30.tar.xz
cd linux-6.6.30

# Verify source integrity
ls -la

Code explanation:

  • wget: Downloads kernel source archive from official mirror
  • tar -xf: Extracts compressed archive
  • ls -la: Lists contents to verify extraction worked

Expected Output:

drwxr-xr-x   25 user user  4096 May 26 10:15 .
drwxr-xr-x    3 user user  4096 May 26 10:14 ..
-rw-r--r--    1 user user   496 May 26 10:15 COPYING
-rw-r--r--    1 user user 98113 May 26 10:15 CREDITS
drwxr-xr-x    4 user user  4096 May 26 10:15 Documentation

Alternative: Using Git

What we’re doing: Getting kernel source with git for easier updates and version control.

# Clone kernel repository (alternative method)
git clone --depth 1 --branch v6.6.30 \
    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

# Enter source directory
cd linux

Code explanation:

  • --depth 1: Only downloads latest commit to save bandwidth
  • --branch v6.6.30: Gets specific kernel version
  • Git method allows easier updates and patch management

Step 3: Configure Kernel

Starting with Base Configuration

What we’re doing: Creating initial kernel configuration based on current system.

# Copy current system config as starting point
zcat /proc/config.gz > .config

# Or use default Alpine config
make defconfig

# Start interactive configuration
make menuconfig

Code explanation:

  • /proc/config.gz: Contains configuration of currently running kernel
  • defconfig: Creates minimal default configuration
  • menuconfig: Opens text-based configuration interface

Important Configuration Areas:

Navigate through these sections in menuconfig:

General Setup
├── Local version (add custom identifier)
├── Kernel compression (choose lz4 for faster boot)
└── Control Group support (enable if using containers)

Processor Type and Features
├── Processor family (select your CPU type)
├── Maximum number of CPUs (match your hardware)
└── Preemption Model (choose based on use case)

Device Drivers
├── Block devices (enable what you need)
├── Network device support (your network cards)
├── Graphics support (if using desktop)
└── USB support (usually needed)

Custom Configuration Example

What we’re doing: Modifying configuration for a minimal server system.

# Enable specific features programmatically
scripts/config --enable CONFIG_IKCONFIG
scripts/config --enable CONFIG_IKCONFIG_PROC
scripts/config --disable CONFIG_SOUND
scripts/config --disable CONFIG_DRM

# Set local version string
scripts/config --set-str CONFIG_LOCALVERSION "-custom"

Code explanation:

  • --enable CONFIG_IKCONFIG: Makes config available in /proc
  • --disable CONFIG_SOUND: Removes audio support for servers
  • --set-str CONFIG_LOCALVERSION: Adds custom identifier to kernel version

Tip: I always enable CONFIG_IKCONFIG so I can see how the kernel was configured later.

Step 4: Compile the Kernel

Building Kernel and Modules

What we’re doing: Compiling the kernel source code into bootable image and loadable modules.

# Clean any previous builds
make clean

# Compile kernel with parallel jobs
make -j$(nproc) bzImage modules

# Check compilation progress
echo "Kernel compilation completed"

Code explanation:

  • make clean: Removes any leftover build files
  • -j$(nproc): Uses all available CPU cores for faster compilation
  • bzImage: Creates compressed bootable kernel image
  • modules: Builds loadable kernel modules

Expected Output:

  CC      kernel/fork.o
  CC      kernel/exec_domain.o
  CC      kernel/panic.o
  ...
  LD [M]  drivers/net/ethernet/intel/e1000e/e1000e.ko
Kernel: arch/x86/boot/bzImage is ready

Warning: Compilation can take 30 minutes to several hours depending on your hardware and configuration.

Installing Modules

What we’re doing: Installing compiled kernel modules to system directories.

# Install modules to /lib/modules
sudo make modules_install

# Verify modules were installed
ls /lib/modules/

Code explanation:

  • modules_install: Copies compiled modules to standard location
  • Modules are needed for hardware drivers and filesystem support

Step 5: Install Custom Kernel

Installing Kernel Image

What we’re doing: Copying the compiled kernel to boot directory and updating bootloader.

# Copy kernel to boot directory
sudo cp arch/x86/boot/bzImage /boot/vmlinuz-6.6.30-custom

# Copy system map for debugging
sudo cp System.map /boot/System.map-6.6.30-custom

# Copy kernel config for reference
sudo cp .config /boot/config-6.6.30-custom

Code explanation:

  • vmlinuz-6.6.30-custom: Bootable kernel image with custom name
  • System.map: Symbol table for kernel debugging
  • config: Configuration used to build this kernel

Creating Initial RAM Disk

What we’re doing: Building initramfs that loads before root filesystem.

# Generate initramfs for custom kernel
sudo mkinitfs -k 6.6.30-custom -o /boot/initramfs-6.6.30-custom

# Verify initramfs was created
ls -lh /boot/initramfs-6.6.30-custom

Code explanation:

  • mkinitfs: Alpine tool for creating initial RAM filesystem
  • -k 6.6.30-custom: Specifies kernel version for module loading
  • Initramfs contains essential drivers needed for boot process

Step 6: Configure Bootloader

Updating GRUB Configuration

What we’re doing: Adding custom kernel entry to bootloader menu.

# Edit GRUB configuration
sudo nano /etc/default/grub

# Add custom entry
echo 'GRUB_DEFAULT=0' | sudo tee -a /etc/default/grub

# Update GRUB configuration
sudo grub-mkconfig -o /boot/grub/grub.cfg

Configuration example:

Before:

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Alpine"

After:

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Alpine"
GRUB_CMDLINE_LINUX_DEFAULT="quiet"

Manual GRUB Entry

What we’re doing: Creating specific boot entry for custom kernel.

# Add custom entry to GRUB configuration
sudo tee -a /etc/grub.d/40_custom <<EOF
menuentry 'Alpine Linux (Custom Kernel 6.6.30)' {
    linux /boot/vmlinuz-6.6.30-custom root=/dev/sda1 ro
    initrd /boot/initramfs-6.6.30-custom
}
EOF

# Regenerate GRUB menu
sudo grub-mkconfig -o /boot/grub/grub.cfg

Code explanation:

  • menuentry: Creates bootloader menu item
  • linux /boot/vmlinuz-6.6.30-custom: Points to our custom kernel
  • root=/dev/sda1: Adjust to match your root partition
  • initrd: Specifies initial RAM disk to load

Step 7: Alpine Linux Installation

Installing Alpine with Custom Kernel

What we’re doing: Setting up Alpine Linux to use our custom kernel by default.

# Mount Alpine installation media
mkdir -p /mnt/alpine
sudo mount /dev/sr0 /mnt/alpine

# Run Alpine setup with custom kernel
sudo setup-alpine

# During setup, choose custom kernel when prompted

Installation Process:

  1. Choose keyboard layout
  2. Set hostname and networking
  3. Configure disk and create partitions
  4. Select custom kernel during package selection
  5. Complete installation process

Post-Installation Kernel Setup

What we’re doing: Ensuring custom kernel is properly integrated after Alpine installation.

# Copy custom kernel files to new installation
sudo cp /boot/vmlinuz-6.6.30-custom /mnt/boot/
sudo cp /boot/initramfs-6.6.30-custom /mnt/boot/
sudo cp -r /lib/modules/6.6.30-custom /mnt/lib/modules/

# Update bootloader in new installation
sudo chroot /mnt update-bootloader

Code explanation:

  • cp /boot/vmlinuz-6.6.30-custom: Copies kernel to new system
  • cp -r /lib/modules/: Copies all kernel modules
  • chroot /mnt: Changes root to new installation for commands
  • update-bootloader: Updates Alpine’s bootloader configuration

Practical Examples

Example 1: Minimal Server Kernel

What we’re doing: Creating optimized kernel for headless server with only essential features.

# Disable unnecessary features for server
scripts/config --disable CONFIG_SOUND
scripts/config --disable CONFIG_DRM
scripts/config --disable CONFIG_FB
scripts/config --disable CONFIG_USB_HID

# Enable server-specific features
scripts/config --enable CONFIG_IKCONFIG
scripts/config --enable CONFIG_CGROUPS
scripts/config --enable CONFIG_NAMESPACES

# Set server-optimized options
scripts/config --enable CONFIG_PREEMPT_NONE
scripts/config --set-val CONFIG_HZ 1000

Code explanation:

  • Disables graphics, sound, and HID devices not needed on servers
  • Enables container support and process isolation features
  • Sets non-preemptive scheduling for better server performance
  • Increases timer frequency for better responsiveness

Example 2: Embedded System Kernel

What we’re doing: Building ultra-minimal kernel for embedded device with 512MB RAM.

# Minimize kernel size
scripts/config --enable CONFIG_CC_OPTIMIZE_FOR_SIZE
scripts/config --disable CONFIG_MODULES
scripts/config --disable CONFIG_SWAP

# Remove debugging features
scripts/config --disable CONFIG_DEBUG_KERNEL
scripts/config --disable CONFIG_PRINTK

# Enable embedded-specific features
scripts/config --enable CONFIG_EMBEDDED
scripts/config --set-val CONFIG_LOG_BUF_SHIFT 14

Code explanation:

  • CONFIG_CC_OPTIMIZE_FOR_SIZE: Optimizes for smallest binary size
  • CONFIG_MODULES: Disables loadable modules to save memory
  • CONFIG_LOG_BUF_SHIFT 14: Reduces kernel log buffer size
  • Removes debugging to reduce kernel size and improve performance

Troubleshooting

Boot Issues

Problem: System won’t boot with custom kernel Solution: Boot from rescue media and check configuration

# Boot from Alpine rescue media
# Mount your root partition
sudo mount /dev/sda1 /mnt

# Check kernel files exist
ls -la /mnt/boot/vmlinuz-6.6.30-custom

# Verify initramfs was created correctly
lsinitramfs /mnt/boot/initramfs-6.6.30-custom | head

Module Loading Problems

Problem: Hardware not working due to missing drivers Solution: Rebuild kernel with required modules

# Check what modules current system uses
lsmod | grep -i network

# Find config option for specific driver
cd linux-source
find . -name "*config*" | xargs grep -i "your_driver_name"

# Enable required driver and rebuild
scripts/config --enable CONFIG_YOUR_DRIVER
make -j$(nproc) bzImage modules

Memory Issues During Build

Problem: Not enough memory for compilation Solution: Use swap or reduce parallel jobs

# Add temporary swap file
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Reduce parallel jobs
make -j2 bzImage modules

Best Practices

  1. Always Keep Working Kernel:

    # Keep old kernel as backup
    sudo cp /boot/vmlinuz /boot/vmlinuz.backup
  2. Version Your Custom Kernels:

    • Use meaningful version strings like -server-v1 or -embedded-v2
    • Keep build logs and configurations
  3. Test Before Production:

    • Always test custom kernels in virtual machines first
    • Verify all required hardware works properly

Verification

To verify the custom kernel installation:

# Check kernel version
uname -r

# Verify custom features are enabled
zcat /proc/config.gz | grep CONFIG_LOCALVERSION

# Check available modules
find /lib/modules/$(uname -r) -name "*.ko" | wc -l

Expected Output:

6.6.30-custom
CONFIG_LOCALVERSION="-custom"
1247

Wrapping Up

You just learned how to:

  • Set up kernel build environment on Alpine Linux
  • Configure and compile custom Linux kernel
  • Install custom kernel with proper module support
  • Integrate custom kernel into Alpine Linux installation

That’s it! You now know how to build and install Alpine Linux with custom kernels. This gives you complete control over your system’s capabilities and performance. I use this technique for specialized servers and embedded systems where standard kernels are too bloated or missing specific features.