Prepare Raspberry Pi SD Card with Ubuntu & Cloud Init
I wanted to setup a new Raspberry Pi machine with pre-configured Wifi & SSH. I also wanted to install Docker. I found a way to do this using cloud-init which is pre-installed on Ubuntu.
To do this, I used the Ubuntu for Raspberry Pi image and cloud-init. I also used the flash tool to flash the image to the Micro SD card.
To configure cloud-init, I created a user-data
file with the following content:
#cloud-config
hostname: pi # it will be overridden via `flash -n`
locale: en_US.UTF-8
manage_etc_hosts: true
timezone: Asia/Bangkok
# Enable password authentication with the SSH daemon
ssh_pwauth: false
# Create groups
groups:
- docker
# You could modify this for your own user information
users:
# Disable the default ubuntu user
- name: ubuntu
inactive: true
# Create a new user
- name: narze
primary-group: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users,docker,adm,dialout,audiolugdev,netdev,video
ssh-import-id: None
lock_passwd: true
ssh-authorized-keys: # Replace with your own public keys
- ssh-ed25519 AAAA................
# Install additional packages on first boot
package_update: true
package_upgrade: true
packages:
- avahi-daemon
- ca-certificates
- curl
# These commands will be ran once on first boot only
runcmd:
# Install Docker with buildx & compose plugin
- install -m 0755 -d /etc/apt/keyrings
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
- chmod a+r /etc/apt/keyrings/docker.asc
- |
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- systemctl start docker
- systemctl enable docker
# Reboot after cloud-init completes
power_state:
mode: reboot
Note: ssh-authorized-keys
are required since I disabled password authentication. You can replace it with your own public keys.
I also created a network-config
file to configure the Wifi & Ethernet connection:
version: 2
ethernets:
eth0:
dhcp4: true
dhcp6: false
optional: true
wifis:
wlan0:
dhcp4: true
dhcp6: false
optional: true
access-points:
MY_SSID1:
password: "pa$$w0rd"
MY_SSID2:
password: "pa$$w0rd"
Both files are to be placed after flashing the image to the Micro SD card. I used flash to flash the image to the Micro SD card and configure the cloud-init files at the same time:
flash -u ./user-data \
-n narzepi \
-F ./network-config \
./path/to/ubuntu-24.04.1-preinstalled-server-arm64+raspi.img.xz
# Logs
Use /tmp/image.img
No SD card found. Please insert SD card, I'll wait for it...
Is /dev/disk4 correct? y
Unmounting /dev/disk4 ...
Unmount of all volumes on disk4 was successful
Unmount of all volumes on disk4 was successful
Flashing /tmp/image.img to /dev/rdisk4 ...
0+56086 records in
3505+1 records out
3675607040 bytes transferred in 321.957281 secs (11416443 bytes/sec)
Mounting Disk
Mounting /dev/disk4 to customize...
Copying cloud-init ./user-data to /Volumes/system-boot/user-data ...
Copying file ./network-config to /Volumes/system-boot/ ...
Set hostname=narzepi
Unmounting /dev/disk4 ...
"disk4" ejected.
Finished.
When it’s done, insert the Micro SD card to the Raspberry Pi and power it on. It will automatically connect to the Wifi and setup, this will take 5-10 minutes. After that, you can SSH to the Raspberry Pi with [hostname].local
that you created.
ssh narze@narzepi.local