Installing Alpine from rescue mode

Keywords:

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:

  • https://nl.alpinelinux.org/alpine/v3.7/main/x86_64/apk-tools-static-2.8.2-r0.apk
  • https://nl.alpinelinux.org/alpine/v3.7/main/x86_64/alpine-keys-2.1-r1.apk (if you're lazy)

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

Bootloader

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:

setup-hostname
setup-interfaces
setup-apkrepos
setup-timezone

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
    netmask 255.255.255.255
    gateway 172.31.1.1
    pointopoint 172.31.1.1

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