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.13} | |
APKTOOLS_VERSION=2.12.1-r0 | |
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 | |
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; } | |
trap 'rm -r $apkdir' EXIT | |
$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=2021.02.01 | |
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) | |
wget "$MIRROR/iso/$ISO_DATE/archlinux-bootstrap-$ISO_DATE-x86_64.tar.gz" -O $tarfile | |
trap 'rm $tarfile' EXIT | |
mkdir -p "$dest" | |
tar -xzf $tarfile -C "$dest" --strip-components=1 | |
printf 'Server = %s/$repo/os/$arch\n' $MIRROR >"$dest"/etc/pacman.d/mirrorlist | |
rm "$dest/etc/resolv.conf" # systemd configures this | |
for i in $(seq 0 10); do # https://github.com/systemd/systemd/issues/852 | |
echo "pts/$i" >>"$dest/etc/securetty" | |
done | |
cat >"$dest"/setup.sh <<SCRIPT | |
pacman-key --init && pacman-key --populate archlinux | |
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:-focal} | |
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) | |
wget "http://cloud-images.ubuntu.com/${CODENAME}/current/${CODENAME}-server-cloudimg-amd64-root.tar.xz" -O $rootfs | |
trap 'rm $rootfs' EXIT | |
mkdir -p "$dest" | |
tar -xaf $rootfs -C "$dest" | |
sed '/^root:/ s|\*||' -i "$dest/etc/shadow" # passwordless login | |
rm "$dest/etc/resolv.conf" # systemd configures this | |
for i in $(seq 0 10); do # https://github.com/systemd/systemd/issues/852 | |
echo "pts/$i" >>"$dest/etc/securetty" | |
done | |
echo >"$dest/etc/fstab" | |
systemd-nspawn -q -D "$dest" /bin/systemctl disable \ | |
ssh systemd-{timesyncd,networkd-wait-online,resolved} | |
# packages that are useless inside container | |
systemd-nspawn -q -D "$dest" /usr/bin/apt-get -qq satisfy -y --purge 'Conflicts: lxcfs, lxd, snapd' || \ | |
systemd-nspawn -q -D "$dest" /usr/bin/apt-get -qq purge --autoremove snapd lxcfs lxd | |
echo "" | |
echo "Ubuntu $CODENAME container was created successfully" |
This comment has been minimized.
This comment has been minimized.
Thank you, very useful scripts, saved a lot of time. |
This comment has been minimized.
This comment has been minimized.
My fork of your script is here: https://github.com/mikhailnov/rootfs-scripts/blob/master/rootfs-ubuntu.sh |
This comment has been minimized.
This comment has been minimized.
Starting alpine image on Ubuntu 20 gives
but
works.
does not seem to work. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Awesome, thank you for sharing the script.
It's a little bit ugly but I change to use edge instead.