Headless setup of Alpine Linux on the Raspberry Pi

Alpine Linux is a lightweight Linux distribution which has gained popularity mainly as a base image for Docker containers. It is also a good candidate for a small system like the Raspberry Pi. However, I couldn't find out how to do a headless setup, i.e. one without a monitor or keyboard, but rather just a network connection and SSH, unlike what's easily possible with Raspbian.

This post explains how to do it. The process is a bit more convoluted, which is specially inconvenient since you can't get feedback from a monitor, but it can be done. Additionally, an important limitation is that you will need an Ethernet connection for the initial setup, not a wireless connection.


To start, you will need to generate an SSH public/private key pair using ssh-keygen, which you will use to authenticate through SSH once the system is ready.

Afterwards, follow the Raspberry Pi "Preparation" section in the Alpine Linux Wiki, up to the point where you have extracted the root filesystem on the SD card.

Now, this is where the magic comes: It turns out that Alpine Linux's initramfs accepts some additional parameters in the kernel command line that allow us to initialize the network and add an SSH public key to the .ssh/authorized_keys file. Those are a bit obscure, yet more or less documented and perfect for our headless setup use case. We can add those parameters in the cmdline.txt file in the root of the SD card in order to get a SSH connection after the system boots for the first time.

  • The ip parameter theoretically accepts the value ip=dhcp for automatic IP assignment. However, this resulted in a boot failure in my experience, so we will use the static IP format instead. For a typical home network, this should look like the following: ip=192.168.1.222::192.168.1.1:255.255.255.0::eth0::192.168.1.1: (where 192.168.1.222 is the IP that the Raspberry Pi will have after booting). Note: You will be able to switch to DHCP after the initial setup.

  • The ssh_key parameter accepts an URL to an SSH public key. You can decide to upload your SSH public key somewhere, but if you have a computer on your same network as the Raspberry, an easy alternative is to serve the key yourself using e.g. Python's built-in HTTP server:

    [~/temp_folder]$ ls
    mykey.pub
    [~/temp_folder]$ cat mykey.pub
    ssh-rsa blablablablabla root@mykey
    [~/temp_folder]$ python -m http.server 8080
    Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
    

    For this setup, the parameter should look like the following: ssh_key=http://192.168.1.111:8080/mykey.pub (where 192.168.1.111 is the IP of the computer serving the key).

Add those two parameters together in the cmdline.txt file in the root of the SD card, so the entire file should look like the following:

modules=loop,squashfs,sd-mod,usb-storage quiet console=tty1 ip=192.168.1.222::192.168.1.1:255.255.255.0::eth0::192.168.1.1: ssh_key=http://192.168.1.111:8080/mykey.pub

Finally, unmount the SD card and try to boot your Raspberry with it. After a bit (the first boot will take longer than usual due to SSH key generation), it should boot correctly and make an SSH server available. Otherwise, make sure you haven't missed any step from the regular Alpine setup, and check if the system responds to ping or if it fetched the SSH key to diagnose the problem.

If everything went well, you should be able to log as the root user through SSH:

[~]$ ssh root@192.168.1.222 -i mykey
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

localhost:~# 

After this, follow the steps in the Alpine Linux Wiki and run setup-alpine to install the system. Afterwards, make sure to persist the SSH key with lbu, in order to keep SSH access across reboots:

localhost:~# lbu include /root/.ssh/authorized_keys 
localhost:~# lbu commit -d

Finally, shut down the Raspberry, plug the SD card back into your computer, and remove the ip and ssh_key parameters from cmdline.txt. You should now have a clean, SSH-accessible Alpine Linux install on your Raspberry Pi.

links

social