Skip to content

Instantly share code, notes, and snippets.

@sfan5
Last active October 20, 2023 08:45
  • Star 41 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
bootable systemd-nspawn containers with Linux distributions: Alpine, Arch Linux, Ubuntu
#!/bin/bash -e
# Creates a systemd-nspawn container with Alpine
MIRROR=http://dl-cdn.alpinelinux.org/alpine
VERSION=${VERSION:-v3.18}
APKTOOLS_VERSION=2.14.0-r2
if [ $UID -ne 0 ]; then
echo "run this script as root" >&2
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <destination>" >&2
exit 0
fi
dest="$1"
apkdir=$(mktemp -d)
guestarch=x86
[ "$(uname -m)" == x86_64 ] && guestarch=x86_64
trap 'rm -r $apkdir' EXIT
wget -qO- $MIRROR/latest-stable/main/x86/apk-tools-static-$APKTOOLS_VERSION.apk \
| tar -xz -C $apkdir || \
{ echo "Couldn't download apk-tools, the version might have changed..."; exit 1; }
$apkdir/sbin/apk.static \
-X $MIRROR/$VERSION/main -U --arch $guestarch \
--allow-untrusted --root "$dest" \
--initdb add alpine-base
mkdir -p "$dest"/{etc/apk,root}
printf '%s/%s/main\n' $MIRROR $VERSION >"$dest"/etc/apk/repositories
for i in $(seq 0 10); do # https://github.com/systemd/systemd/issues/852
echo "pts/$i" >>"$dest/etc/securetty"
done
# make console work
sed '/tty[0-9]:/ s/^/#/' -i "$dest"/etc/inittab
printf 'console::respawn:/sbin/getty 38400 console\n' >>"$dest"/etc/inittab
# minimal boot services
for s in hostname bootmisc syslog; do
ln -s /etc/init.d/$s "$dest"/etc/runlevels/boot/$s
done
for s in killprocs savecache; do
ln -s /etc/init.d/$s "$dest"/etc/runlevels/shutdown/$s
done
echo ""
echo "Alpine $VERSION container was created successfully."
#!/bin/bash -e
# Creates a systemd-nspawn container with Arch Linux
MIRROR=http://mirror.fra10.de.leaseweb.net/archlinux
ISO_DATE=latest
PKG_GROUPS="base"
if [ $UID -ne 0 ]; then
echo "run this script as root" >&2
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <destination>" >&2
exit 0
fi
dest="$1"
tarfile=$(mktemp)
trap 'rm $tarfile' EXIT
wget "$MIRROR/iso/$ISO_DATE/archlinux-bootstrap-x86_64.tar.gz" -O $tarfile
mkdir -p "$dest"
tar -xzf $tarfile -C "$dest" --strip-components=1 --numeric-owner
printf 'Server = %s/$repo/os/$arch\n' $MIRROR >"$dest"/etc/pacman.d/mirrorlist
sed '/^root:/ s|\*||' -i "$dest/etc/shadow" # passwordless login
rm "$dest/etc/resolv.conf" # systemd configures this
# https://github.com/systemd/systemd/issues/852
[ -f "$dest/etc/securetty" ] && \
printf 'pts/%d\n' $(seq 0 10) >>"$dest/etc/securetty"
cat >"$dest"/setup.sh <<SCRIPT
pacman-key --init && pacman-key --populate
pacman -Sy --noconfirm --needed ${PKG_GROUPS}
rm /setup.sh
SCRIPT
systemd-nspawn -q -D "$dest" sh /setup.sh
echo ""
echo "Arch Linux container was created successfully (bootstrapped from $ISO_DATE)"
#!/bin/bash -e
# Creates a systemd-nspawn container with Ubuntu
CODENAME=${CODENAME:-jammy}
if [ $UID -ne 0 ]; then
echo "run this script as root" >&2
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 <destination>" >&2
exit 0
fi
dest="$1"
rootfs=$(mktemp)
trap 'rm $rootfs' EXIT
wget "http://cloud-images.ubuntu.com/${CODENAME}/current/${CODENAME}-server-cloudimg-amd64-root.tar.xz" -O $rootfs
mkdir -p "$dest"
tar -xaf $rootfs -C "$dest" --numeric-owner
sed '/^root:/ s|\*||' -i "$dest/etc/shadow" # passwordless login
rm "$dest/etc/resolv.conf" # systemd configures this
# https://github.com/systemd/systemd/issues/852
[ -f "$dest/etc/securetty" ] && \
printf 'pts/%d\n' $(seq 0 10) >>"$dest/etc/securetty"
>"$dest/etc/fstab"
systemd-nspawn -q -D "$dest" /bin/systemctl disable \
ssh systemd-{timesyncd,networkd-wait-online,resolved}
# uninstall some packages
systemd-nspawn -q -D "$dest" /usr/bin/apt-get -qq satisfy -y --purge 'Conflicts: lxcfs, lxd, snapd, cloud-init' || \
systemd-nspawn -q -D "$dest" /usr/bin/apt-get -qq purge --autoremove snapd lxcfs lxd cloud-init
echo ""
echo "Ubuntu $CODENAME container was created successfully"
@Jip-Hop
Copy link

Jip-Hop commented Jan 2, 2023

Thanks for this script! Building my own based on yours :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment