Create a New Raspberry Pi Boot Image From Scratch#
Introduction#
IMPORTANT: normal operation for setting up a new Raspberry Pi is to use the provided pre-built image sdcards. See Commissioning a new Raspberry Pi Server.
This page is only useful if you need to create a completely new sdcard with a new image, perhaps because a new version of Raspberry Pi OS has been released.
If you just want to update an existing image, e.g. to update the version of usb-remote it uses see Updating an Existing Raspberry Pi Boot Image.
Prerequisites#
You will need:
A computer running Linux on which you have full sudo privileges.
A microSD card of at least 16GB capacity.
A microSD card reader connected to your computer.
A Raspberry Pi 4 or 5 to run the image on see Recommend Hardware.
A USB stick of at least 8GB capacity to store the backup image.
Possibly a monitor and microHDMI to HDMI cable if you want to use the Pi GUI.
Options#
The sequence of events to set this up is:
Image the microSD card with Raspberry Pi OS.
Boot a Raspberry Pi from the microSD card and do some additional configuration.
Take a backup image of the microSD card to use as an image for creating more sdcards.
In order to connect to the Raspberry Pi for configuration you have two options:
Connect a monitor and keyboard to the Raspberry Pi directly. Make sure you use the “Raspberry Pi OS” version which includes the GUI.
Connect via SSH to the Raspberry Pi’s IP address. For this to work you need to be able to determine (or fix) the Raspberry Pi’s IP address on your network.
In both cases you will need access to the internet from the Raspberry Pi to download and install packages. Your options are:
Make sure that your Pi is connected to your wired ethernet network which has internet access.
Temporarily connect to Wifi to get internet access during setup. At DLS the GovWiFi network is an easy option for this. You will need to use the GUI option above to set up the Wifi connection.
Bear in mind that the preferred production configuration for usb-remote Raspberry Pis is to have no internet access and only use wired ethernet with a DHCP assigned IP address. The temporary internet access is only needed to download and install packages during setup.
Step 1 Image the microSD Card with Raspberry Pi OS#
Download the latest ‘Raspberry Pi OS Lite’ image from the Raspberry Pi website. The Lite version is the last option on the linked page.
If you need the Pi desktop GUI, then use ‘Raspberry Pi OS’ image.
Use
lsblkto get a list of block devices on your system before inserting the microSD card.Insert the microSD card into your card reader and connect it to your computer.
Use
lsblkagain to identify the device name of the microSD card (e.g./dev/sdb).uncompress the downloaded Raspberry Pi OS image.
cd ~/Downloads unxz ./2025-12-04-raspios-trixie-arm64-lite.img.xz
Use
ddto write the Raspberry Pi OS image to the microSD card. Replace/dev/sdXwith the actual device name of your microSD card. Be very careful with this command as it will overwrite the specified device.sudo dd if=./2025-12-04-raspios-trixie-arm64-lite.img of=/dev/sdX bs=4M status=progress conv=fsync
Step 2 Configure the Raspberry Pi OS Image#
IMPORTANT: These steps must be done before the first boot of the Raspberry Pi. The files we set up here are only read by the Raspberry Pi during its first boot.
Mount the microSD card boot partition. Replace
/dev/sdX1with the actual device name of the boot partition of your microSD card.mkdir sdcard-bootfs sudo mount /dev/sdX1 sdcard-bootfs cd sdcard-bootfs
Enable SSH by creating an empty file named
sshin the boot partition.sudo touch ssh
Create a user
localwith passwordlocalby adding a file nameduserconfin the boot partition.echo "local:$(echo local | openssl passwd -6 -stdin)" | sudo tee userconf.txt
If you need a static IP address for wired ethernet, edit
cmdline.txt.sudo vim /boot/cmdline.txt # add " ip=<your_static_ip_address>" at the end of the single line in the file.
Finally unmount the boot partition.
cd .. sudo umount sdcard-bootfs # there may also be a second mount point: sudo umount /dev/sdX rmdir sdcard-bootfs
Step 3 First Boot and Connect to Internet#
Insert the microSD card into your Raspberry Pi and power it on.
Your options for connecting to the Raspberry Pi are:
Connect a monitor and keyboard to the Raspberry Pi directly. This is not available if you are using the ‘Lite’ version and requires a microHDMI to HDMI cable and a monitor.
Connect via SSH to the Raspberry Pi’s IP address. The username is
localand the password islocal. If you have access to your router then it will show the Raspberry Pi’s IP address in its connected devices list. The best alternative is to set a fixed IP in the boot configuration as described above.
If you do not have internet access then temporarily connect to Wifi:
sudo raspi-config
Select “System Options” -> “Wireless LAN”
Enter your SSID and password
Finish
ping google.com to check internet access (try
sudo rebootif it does not work immediately) If you need to connect to GovWiFi then you require the GUI version of the OS see Connecting to GovWiFi.
Once connected, update the package lists and upgrade installed packages, plus get vim and git.
sudo apt update sudo apt upgrade -y sudo apt install -y git vim
Take this opportunity to write down the Raspberry Pi’s MAC address for future reference.
ip link show eth0 # look for "link/ether xx:xx:xx:xx:xx:xx"
Step 4 Install and Configure usbip#
Add the kernel modules to
/etc/modules-load.dso they load at boot.sudo modprobe usbip_core sudo modprobe usbip_host echo -e "usbip-core\nusbip-host" | sudo tee /etc/modules-load.d/usbip.conf
Install the
usbippackage.sudo apt install -y usbip
Create a service to run uspipd at boot.
echo "[Unit] Description=USB/IP Daemon After=network.target [Service] Type=forking ExecStart=/usr/sbin/usbipd -D Restart=on-failure [Install] WantedBy=multi-user.target" | sudo tee /etc/systemd/system/usbipd.service sudo systemctl enable --now usbipd.service sudo systemctl status usbipd.service
Step 5 Install usb-remote#
Install
uv.curl -LsSfO https://astral.sh/uv/install.sh sudo bash install.sh
Install
usb-remotesystem service.sudo -s # uv (installed by root) requires the root profile so use sudo -s uvx usb-remote install-service server systemctl enable --now usb-remote systemctl status usb-remote # check it is running correctly exit
Step 6 image-backup#
image-backup is a utility to create backup images of Raspberry Pi sdcards. It does clever stuff like minimizing the size of the image and expanding the filesystem on first boot of copies of the image. See https://forums.raspberrypi.com/viewtopic.php?t=332000 for more details.
Clone the image-backup repository.
cd ~ git clone https://github.com/seamusdemora/RonR-RPi-image-utils.git
Install image-backup.
sudo install --mode=755 ~/RonR-RPi-image-utils/image-* /usr/local/sbin
Step 7 Clean Up The Settings for Production#
The master sdcard image wants to use DHCP only and be isolated from the internet so we need to undo any temporary configuration changes made earlier. This allows us to re-use the image on multiple Raspberry Pis which will each get their own IP address via DHCP.
Disable the static IP address if you set one up.
sudo vim /boot/firmware/cmdline.txt # remove " ip=<your_static_ip_address>" that you added earlier
Disable Wifi if you enabled it.
sudo vim /boot/firmware/config.txt # add the following lines at the end of the file dtoverlay=disable-wifi dtoverlay=disable-bt
Step 8 Prepare the Backup Image for Distribution#
Add a run-once service to the image so that when copies of the image are first booted they will enable read-only mode (after the root filesystem has been expanded - this feature is added automatically by image-backup).
Read-only mode uses overlayfs in RAM to avoid wearing out the sdcard and makes the Pi reset to a clean state on each boot.
Set up a run once service for first boot of copies of the image.
echo '[Unit] Description=Run script once on next boot ConditionPathExists=/var/local/runonce.sh After=multi-user.target [Service] Type=oneshot ExecStart=/bin/bash /var/local/runonce.sh [Install] WantedBy=multi-user.target ' | sudo tee /etc/systemd/system/runonce.service sudo systemctl enable runonce.service
Create the
runonce.shscript to expand the root filesystem and enable read-only mode.echo '#!/bin/bash set -x # Disable this script from running again mv /var/local/runonce.sh /var/local/runonce.sh.done # disable services that will report errors when in RO mode systemctl mask dphys-swapfile.service systemctl mask systemd-zram-setup@zram0.service # enable read only overlay mode raspi-config nonint do_overlayfs 0 # reboot to pick up the change sync; reboot ' | sudo tee /var/local/runonce.sh # Add packages required for read-only mode sudo apt-get -y install cryptsetup cryptsetup-bin overlayroot
Step 9 Add a Service to Send the MAC Address to a Pico (optional)#
Adding this service will monitor USB ports for a Raspberry Pi Pico being plugged in. When a Pico is detected it will send the Pi’s MAC address to the Pico.
This is useful for commissioning new usb-remote servers using a Pico as described in Setup Raspberry Pi Pico for MAC Address Display.
echo '[Unit]
Description=Monitor USB and send MAC address to any pico detected
After=multi-user.target
[Service]
ExecStart=/root/.local/bin/uvx --from usb-remote pico-send-mac
[Install]
WantedBy=multi-user.target
' | sudo tee /etc/systemd/system/send-mac.service
sudo systemctl enable send-mac --now
Step 10 Create a Backup Image of the microSD Card#
Before backing up the image we put the SD card into read-only mode. This avoids wearing out the SD card and makes the Pi reset to a clean state on each boot.
Insert a USB stick into the Raspberry Pi to store the backup image.
use
lsblkto identify the device name of the USB stick 1st partition which will normally be/dev/sda1. Mount the USB stick at/media/local/usb:sudo mkdir -p /media/local/usb sudo mount /dev/sda1 /media/local/usb
Run the image-backup script to create a backup image of the microSD card to the USB stick. Replace the output file name with something appropriate including the version of usb-remote.
sudo image-backup # when promted for output file, use something like: /media/local/usb/raspi-lite-usb-remote-2.2.2.img # choose the defaults for the other prompts and y to confirm file creation.
sync and unmount the USB stick.
sync sudo umount /media/local/usb
You can now remove the USB stick.
That’s it. Your img file can now be used to create additional Raspberry Pi usb-remote servers as needed.
To find out how to commission additional Raspberry Pi servers from this image see Commissioning Additional Raspberry Pi Servers.
Conclusion#
You now have a backup image of your configured Raspberry Pi microSD card that you can use to create additional Raspberry Pi servers as needed.
See Commissioning Additional Raspberry Pi Servers for instructions on deploying the backup image to new Raspberry Pis.