If you are running your Raspberry Pi devices completely headless, connecting them to a monitor and keyboard only for the sake of setting them up may be a chore. Luckily, it is pretty easy to prepare the SD card for the Raspberry Pi such as the rest of the setup can be run headlessly.

First, we grab the OS image and write the SD card with it.

wget http://cdimage.ubuntu.com/releases/20.04/release/ubuntu-20.04-preinstalled-server-arm64+raspi.img.xz
echo "48167067d65c5192ffe041c9cc4958cb7fcdfd74fa15e1937a47430ed7b9de99 *ubuntu-20.04-preinstalled-server-arm64+raspi.img.xz" | shasum -a 256 --check
unxz ubuntu-20.04-preinstalled-server-arm64+raspi.img.xz
lsblk
# if your sd card is at /dev/sda for instance
sudo dd if=ubuntu-20.04-preinstalled-server-arm64+raspi.img of=/dev/sda bs=8M

Next, we’ll mount our SD card locally.

mkdir -p /mnt/sda1 /mnt/sda2
sudo mount /dev/sda1 /mnt/sda1
sudo mount /dev/sda2 /mnt/sda2

Once the Pi boots up, we’ll want to be able to SSH into it to perform the rest of the setup. This can be done by leaving an empty file named ssh inside the boot partition.

touch /mnt/sda1/ssh

You can also use this opportunity to edit cmdline.txt and usercfg.txt. In my case I wanted to enable some cgroups (cgroup_enable=cpuset cgroup_enable=memory) and turn off WiFi and Bluetooth (dtoverlay=disable-wifi and dtoverlay=disable-bt).

Add any network configuration to be applied at first boot (netplan).

vi /mnt/sda1/network-config

Inside /mnt/sda2 you can either add some entries in .ssh/authorized_keys in advance, or temporarily enable password-based SSH login in etc/ssh/sshd_config.

Now when you boot your new Pi with the SD card set up above, you should be able to SSH into it momentarily and perform any additional setup.