Raspberry Pi - Headless Installation

From Alpine Linux
Revision as of 12:06, 23 June 2021 by Davidmytton (talk | contribs) (Updated instructions for Alpine 3.14 and Raspberry Pi 4. setup-alpine now does most of the work. Also updated links to move code / download to GitHub as a more permanent location.)
Jump to: navigation, search

The Alpine Linux documentation assumes you have a way to access your system directly, such as via a display and keyboard. However, there are many cases where you might want to deploy a headless box, such as on a Raspberry Pi connected via ethernet (or wifi).

These instructions explain how to install Alpine Linux onto a headless Raspberry Pi, also available on GitHub (with the overlay directory structure and headless script).

See also the generic Raspberry Pi installation instructions. Thanks for the original instructions from the user sodface, who also hosted the overlay files on their website (download). Moved to GitHub as a more permanent location.

Tested on

  • Alpine Linux 3.14.
  • Raspberry Pi 4 Model B - 4GB.

1 - Prepare the SD card

The SD card needs at least 2 partitions, one FAT32 boot partition and then at least 1 more Linux type partition. This assumes you have installed fdisk and want to wipe the SD card.

  1. Check the name of the device using fdisk -l - in my case it is /dev/mmcblk0.
  2. Launch fdisk against the device: fdisk /dev/mmcblk0
  3. If necessary, remove all existing partitions using the d command.
  4. se the n command to create a new primary partition in position 1. Accept the default start placement and set +256M for the end position. Use the t command to set the type to WIN 95 FAT32 (LBA).
  5. Use the n command to create a second primary partition in position 2. Accept the default start placement and allow it to use the remainder of the disk. Use the t command to set the type to Linux.
  6. Use the a command to toggle the partition as bootable.
  7. Enter w to write the changes to the SD card.
  8. Assuming you now have two partitions called /dev/mmcblk1p1 and /dev/mmcblk1p2 (check with fdisk -l), create the filesystem:

mkdosfs -F 32 /dev/mmcblk1p1

mkfs.ext4 /dev/mmcblk1p2

2 - Copy the Alpine system to the SD card

You now need to copy the latest Alpine download to the bootable partition on the SD card and create the headless configuration overlay file. A pre-packaged version is provided in the releases of this GitHub repo.

  1. Mount the disk: mkdir /mnt/sd1 then mount /dev/mmcblk1p1 /mnt/sd1.
  2. cd /mnt/sd1 then download the latest Alpine release. For a Raspberry Pi 4 this is the aarch64 Raspberry Pi release.
  3. Extract the tar to the current directory: tar xvfz alpine-rpi-3.14.0-aarch64.tar.gz
  4. Download the headless overlay file. This should then exist at /mnt/sd1/headless.apkovl.tar.gz. Do not extract it.
  5. Unmount: umount /mnt/sd1

Optional: Wi-Fi config

If you want the Raspberry Pi to connect to the network over wifi, before you unmount, create a file called /mnt/sd1/wifi.txt with the format:

ssid password

Otherwise if you do not create this file, the default connection will be wired.

3 - Boot the Raspberry Pi

In the past it was necessary to run the manual setup scripts, but Alpine now correctly detects the Raspberry Pi and knows that SSH is already running. The standard setup script can therefore be used to finish the configuration:

  1. Insert the SD card into the Raspberry Pi and then boot it up. Check your router to find out what IP address gets assigned.
  2. SSH to the appropriate IP address as root with no password. Alpine will be running in diskless mode.
  3. Run setup-alpine and follow the instructions. It will report there are no available disks and ask you to pick one. Assuming your SD card device is called mmcblk0 then choose that device. It will ask you if you want to erase the disk and then configure it as a persistent disk.
  4. Reboot.
  5. Create a new user to log into future sessions as.


Overlay directory structure

└── etc ├── .default_boot_services ├── local.d │ └── headless.start └── runlevels └── default └── local -> /etc/init.d/local


etc/local.d/headless.start is as follows (note that the cat heredoc identation in the functions needs to be tabs):

Contents of etc/local.d/headless.start

#!/bin/sh __create_eni() { cat <<-EOF > /etc/network/interfaces auto lo iface lo inet loopback auto ${iface} iface ${iface} inet dhcp hostname localhost EOF } __create_eww() { cat <<-EOF > /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="${ssid}" psk="${psk}" } EOF } __edit_ess() { cat <<-EOF >> /etc/ssh/sshd_config PermitEmptyPasswords yes PermitRootLogin yes EOF } __find_wint() { for dev in /sys/class/net/* do if [ -e "${dev}"/wireless -o -e "${dev}"/phy80211 ] then echo "${dev##*/}" fi done } ovlpath=$(find /media -name *.apkovl.tar.gz -exec dirname {} \;) read ssid psk < "${ovlpath}/wifi.txt" if [ ${ssid} ] then iface=$(__find_wint) apk add wpa_supplicant __create_eww rc-service wpa_supplicant start else iface="eth0" fi __create_eni rc-service networking start /sbin/setup-sshd -c openssh cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig __edit_ess rc-service sshd restart mv /etc/ssh/sshd_config.orig /etc/ssh/sshd_config

Packaging the overlay

cd overlay

chmod +x etc/local.d/headless.start

tar czvf headless.apkovl.tar.gz etc/