Skip to content

popovicu/alpine-linux-self-setup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

alpine-linux-self-setup

A single shell script that builds an Alpine Linux sysroot tarball from a JSON config. Relies only on bash, curl, jq, tar, and unshare — all of which ship by default (or via a one-line install) on essentially every mainstream Linux distribution.

Usage

./bootstrap.sh <output.tar> <config.json>

Example:

./bootstrap.sh ./alpine.tar example.json

Then inspect:

tar -tvf alpine.tar | head

Config format

{
  "arch": "x86_64",
  "repos": [
    "https://dl-cdn.alpinelinux.org/alpine/v3.21/main",
    "https://dl-cdn.alpinelinux.org/alpine/v3.21/community"
  ],
  "packages": ["bash", "clang", "openrc"]
}

How it works

  1. Scrapes Alpine's latest-stable/main/x86_64/ directory listing to find the current apk-tools-static-*.apk and downloads it. (latest-stable is an Alpine-maintained symlink, so this stays working as Alpine releases.)
  2. Extracts sbin/apk.static from the apk (an apk is just a tarball).
  3. Lays out a minimal sysroot skeleton in a temp directory.
  4. Enters an unprivileged user namespace via unshare --user --map-root-user, then inside the namespace runs apk.static add ... followed by tar --numeric-owner -cf <output> -C <sysroot> ..

Why tar instead of a populated directory

unshare --map-root-user only fakes UID 0; from the host's view, every other UID created inside the namespace (mail, daemon, wheel, …) collapses to the overflow UID 65534. A directory left on disk would have wrong ownership. Tarring inside the same namespace records the in-namespace UIDs/GIDs into the archive, and a later tar -xf as real root reconstitutes the correct attributes.

Requirements

  • Linux host with unprivileged user namespaces enabled.
  • bash, curl, jq, tar, unshare (util-linux), coreutils.
  • Network access to dl-cdn.alpinelinux.org.

Limitations

  • Host-side apk-tools-static is fetched for x86_64 only. The arch field in the config controls the target sysroot arch (passed to apk.static --arch), but if you build from a non-x86_64 host you'll need to extend the listing URL.
  • Not bit-for-bit reproducible: both apk-tools-static and the package versions resolve against the live Alpine mirror at run time.
  • --allow-untrusted is passed to apk.static add because the sysroot starts with no signing keys. Add alpine-keys first (or vendor the keys) to drop the flag.

About

Build an Alpine Linux sysroot tarball from a JSON config (repos + packages) using only bash, curl, jq, tar, and unshare.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages