Difference between revisions of "Raspberry Pi - Headless Installation"

From Alpine Linux
Jump to: navigation, search
(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.)
Line 1: Line 1:
{{TOC right}}
+
The [https://docs.alpinelinux.org/user-handbook/0.1a/Installing/setup_alpine.html 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).
= Introduction =
 
{{Note|On 6 Feb 2021, I updated the wifi config to just include SSID and Password, per a suggestion via email and it seems to work fine. I've updated the download also. This changes the format of the wifi.txt file originally documented and how the script reads and uses the file. Please update any existing files you are using. Tested with 3.13.1 on Pi Zero W and x86_64 Wyse 3040.|info}}
 
  
This wiki describes a method to prep an sd card for a raspberry pi so that the pi will connect to your local network on first boot and allow password-less root login over ssh to continue setup.  This allows you to setup a raspberry pi without connecting a keyboard or monitor.
+
These instructions explain how to install Alpine Linux onto a headless Raspberry Pi, [https://github.com/davidmytton/alpine-linux-headless-raspberrypi also available on GitHub] (with the overlay directory structure and headless script).
  
This method assumes that you are working from a linux machine and are already familiar with prepping an sd card with Alpine Linux for a raspberry pi. The basic procedure is to first create the sd card as normal but then also copy a one-time use overlay file into the root of the sd card. This file gets extracted on boot and creates /etc/.default_boot_services, enables the local script service, and creates a local startup script.
+
See also the generic [[Raspberry Pi]] installation instructions. Thanks for the original instructions from the user [[User:Sodface|sodface]], who also hosted the overlay files on their website ([http://www.sodface.com/repo/headless.apkovl.tar.gz download]). [https://github.com/davidmytton/alpine-linux-headless-raspberrypi Moved to GitHub] as a more permanent location.
  
The local startup script attempts to read wifi ssid/credential information from a file in the same directory as the custom overlay file named wifi.txt (format described below). If the file does not exist, then eth0 is assumed.
+
===Tested on===
  
I've tested this with Alpine Linux 3.12.0 on a RPi 4, Zero W, A+ and original model A.
+
* Alpine Linux 3.14.
 +
* Raspberry Pi 4 Model B - 4GB.
  
You can download a pre-built overlay file from my website:
+
==1 - Prepare the SD card==
http://www.sodface.com/repo/headless.apkovl.tar.gz
 
  
= Create Overlay File =
+
The SD card needs at least 2 partitions, one FAT32 boot partition and then at
It is assumed that you have already extracted the Alpine Linux archive to the sd card. In a working directory on your local machine (not on the sd card) create the following directory/file structure:
+
least 1 more Linux type partition. This assumes you have installed fdisk and
 +
want to wipe the SD card.
  
{{Cmd|[sodface@sodpro working]$ tree -a
+
# Check the name of the device using <code>fdisk -l</code> - in my case it is <code>/dev/mmcblk0</code>.
└── etc
+
# Launch fdisk against the device: <code>fdisk /dev/mmcblk0</code>
 +
# If necessary, remove all existing partitions using the <code>d</code> command.
 +
# se the <code>n</code> command to create a new primary partition in position 1. Accept the default start placement and set <code>+256M</code> for the end position. Use the <code>t</code> command to set the type to <code>WIN 95 FAT32 (LBA)</code>.
 +
# Use the <code>n</code> 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 <code>t</code> command to set the type to <code>Linux</code>.
 +
# Use the <code>a</code> command to toggle the partition as bootable.
 +
# Enter <code>w</code> to write the changes to the SD card.
 +
# Assuming you now have two partitions called <code>/dev/mmcblk1p1</code> and <code>/dev/mmcblk1p2</code> (check with <code>fdisk -l</code>), create the filesystem:
 +
 
 +
<code>
 +
mkdosfs -F 32 /dev/mmcblk1p1
 +
 
 +
mkfs.ext4 /dev/mmcblk1p2
 +
</code>
 +
 
 +
==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 [https://github.com/davidmytton/alpine-linux-headless-raspberrypi this GitHub repo].
 +
 
 +
# Mount the disk: <code>mkdir /mnt/sd1</code> then <code>mount /dev/mmcblk1p1 /mnt/sd1</code>.
 +
# <code>cd /mnt/sd1</code> then download the latest Alpine release. For a Raspberry Pi 4 this is the <code>aarch64</code> Raspberry Pi release.
 +
# Extract the tar to the current directory: <code>tar xvfz alpine-rpi-3.14.0-aarch64.tar.gz</code>
 +
# Download [https://github.com/davidmytton/alpine-linux-headless-raspberrypi/releases/download/2021.06.23/headless.apkovl.tar.gz the headless overlay file]. This should then exist at <code>/mnt/sd1/headless.apkovl.tar.gz</code>. Do not extract it.
 +
# Unmount: <code>umount /mnt/sd1</code>
 +
 
 +
===Optional: Wi-Fi config===
 +
 
 +
If you want the Raspberry Pi to connect to the network over wifi, before you
 +
unmount, create a file called <code>/mnt/sd1/wifi.txt</code> with the format:
 +
 
 +
<code>
 +
ssid password
 +
</code>
 +
 
 +
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. [https://docs.alpinelinux.org/user-handbook/0.1a/Installing/setup_alpine.html The standard setup script] can therefore be used to finish the configuration:
 +
 
 +
# Insert the SD card into the Raspberry Pi and then boot it up. Check your router to find out what IP address gets assigned.
 +
# SSH to the appropriate IP address as root with no password. Alpine will be running in [[Installation#Diskless_Mode|diskless mode]].
 +
# Run <code>setup-alpine</code> 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 <code>mmcblk0</code> then choose that device. It will ask you if you want to erase the disk and then configure it as a persistent disk.
 +
# Reboot.
 +
# Create a new user to log into future sessions as.
 +
 
 +
==Notes==
 +
===Overlay directory structure===
 +
 
 +
{{Cmd|└── etc
 
     ├── .default_boot_services
 
     ├── .default_boot_services
 
     ├── local.d
 
     ├── local.d
Line 27: Line 74:
 
}}
 
}}
  
Edit etc/local.d/headless.start as follows (note that the cat heredoc identation in the functions needs to be tabs):
+
===headless.start===
 +
 
 +
<code>etc/local.d/headless.start</code> is as follows (note that the cat heredoc identation in the functions needs to be tabs):
  
 
{{Cat|etc/local.d/headless.start|
 
{{Cat|etc/local.d/headless.start|
Line 97: Line 146:
 
}}
 
}}
  
Make the headless.start file executable and create the overlay file:
+
===Packaging the overlay===
 
 
{{Cmd|[sodface@sodpro working]$ chmod +x etc/local.d/headless.start
 
[sodface@sodpro working]$ tar czvf headless.apkovl.tar.gz etc/
 
etc/
 
etc/local.d/
 
etc/local.d/headless.start
 
etc/.default_boot_services
 
etc/runlevels/
 
etc/runlevels/default/
 
etc/runlevels/default/local
 
}}
 
 
 
Copy the headless.apkovl.tar.gz into the root of the sd card and if using wifi, create a wifi.txt file with the following format, replacing ssid and password to match your network.
 
 
 
{{Cat|wifi.txt|
 
ssid password
 
}}
 
Unmount the sd card, insert into the pi and boot.  Monitor your dhcp server and watch for a new lease to determine the IP address assigned to the pi.
 
 
 
Once you know the IP address, you should be able to ssh to the pi as root without a password and continue setup. Do not run the setup-alpine script directly since networking and sshd are already started. The setup script isn't expecting this and things go wrong during the network and repo setup steps. I would recommend running the /sbin/setup-* scripts one at a time, in the following order:
 
 
 
{{Cmd|setup-ntp
 
setup-keymap
 
setup-hostname
 
setup-timezone
 
setup-apkrepos
 
setup-lbu
 
setup-apkcache
 
}}
 
 
 
Set the root password and add a user that you can ssh with after the next reboot.<br>
 
To make sure that new user can sudo, install sudo, run visudo and uncomment one of the lines for the wheel group, then add the new user to the wheel group.
 
{{Cmd|passwd
 
adduser USERNAME
 
apk add sudo
 
visudo
 
addgroup USERNAME wheel
 
}}
 
 
 
I would also recommend installing rng-tools and updating startup services:
 
{{Cmd|apk add rng-tools
 
rc-update add rngd boot
 
rc-update add wpa_supplicant boot
 
rc-update add urandom boot}}
 
 
 
You should delete the overlay file and wifi.txt file (if present) from the sd card, though by default it will be mounted read only. Remount rw to delete those files:
 
{{Cmd|mount -o remount,rw /media/mmcblk0p1
 
rm /media/mmcblk0p1/*.apkovl.tar.gz
 
rm /media/mmcblk0p1/wifi.txt
 
}}
 
  
Remove the local script service from the default runlevel and delete the headless setup script so it's not saved when the new overlay is created later:
+
<code>
 +
cd overlay
  
{{Cmd|rc-update del local default
+
chmod +x etc/local.d/headless.start
rm /etc/local.d/headless.start
 
}}
 
  
Be sure to create a new overlay file before the first reboot:
+
tar czvf headless.apkovl.tar.gz etc/
{{Cmd|lbu commit -d
+
</code>
reboot
 
}}
 

Revision as of 12:06, 23 June 2021

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.

Notes

Overlay directory structure

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

headless.start

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/