Installing Alpine from rescue mode


If you ever feel the need to install Alpine Linux but are unable to install it from (for example) the install ISO, the following steps will get you a working system. You can use this method from e.g. a remote console, on a Dropbear-based initramfs SSH session, locally to another disk, and so on.

Prepare the disk

Assuming you are installing to /dev/sda1 (DOS partitions), no /boot partition:

mkdir /mnt/alpine
mkfs.ext4 /dev/sda1
mount /dev/sda1 /mnt/alpine

If your disk setup is different, adjust accordingly.

Install the Alpine base system

Obtain apk-tools-static for your platform and Alpine version:

[TODO: I have a script for this]

NB: the nl mirror has package listing enabled, which allows you to search for the package by hand if you need. Current URLs:

Alternatively: https://pkgs.alpinelinux.org/packages?name=apk-tools-static&branch=v3.7&arch=x86_64

Also obtain the Alpine packaging keys (alpine-keys), e.g. from another install in /etc/apk/keys. Install them in your target directory:

mkdir -p /mnt/alpine/etc/apk/keys/
cp keys/* /mnt/alpine/etc/apk/keys/

tar xf apk-tools-static-*.apk
./sbin/apk.static --update-cache \
    --repository https://nl.alpinelinux.org/alpine/v3.7/main/ \
    --root /mnt/alpine --initdb alpine-base openssh linux-virthardened syslinux

⚠ Change the kernel package as appropriate. You can also use --allow-untrusted instead of copying the keys.

Complete the base install

Lazily prepare the chroot:

mount -t proc none /mnt/alpine/proc
mount -o bind /sys /mnt/alpine/sys
mount -o bind /dev /mnt/alpine/dev
cp /etc/resolv.conf /mnt/alpine/etc/resolv.conf
chroot /mnt/alpine /bin/ash

Set up OpenRC (TODO: how/where does setup-alpine do this? Unsure!):

rc-update add bootmisc boot
rc-update add devfs sysinit
rc-update add dmesg sysinit
rc-update add hwdrivers sysinit
rc-update add mdev sysinit
rc-update add hostname boot
rc-update add hwclock boot
rc-update add sysctl boot
rc-update add syslog boot
rc-update add modules boot
rc-update add killprocs shutdown
rc-update add mount-ro shutdown
rc-update add savecache shutdown
rc-update add networking default
rc-update add sshd default


Set up syslinux: First edit /etc/update-extlinux.conf by adding the UUID of /dev/sda1 to root= (and I usually set the timeout to 1) – blkid -o export /dev/sda1 | grep '^UUID='

dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sda
extlinux --install /boot
update-extlinux # ?

⚠ Use gptmbr.bin if you’re using GPT

Base configuration

Configure the usual:


Don’t forget to set a root password, and so on.

Hetzner VPS protip

Hetzner gives out /32 addresses with a private-address gateway. The following will work:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address vps-ipv4-address

iface eth0 inet6 static
    address vps-ipv6-address
    netmask 64
    gateway fe80::1