Which versions this covers
The steps follow the official getting started guide for Raspberry Pi OS based on Debian 13 "trixie", the current release on the Raspberry Pi OS downloads page, written with Raspberry Pi Imager 2. Three changes make a lot of older Pi tutorials wrong:
- There is no default
piuser. Since the April 2022 update you create the account yourself, in Imager or at first boot. - Networking is NetworkManager, not dhcpcd. Since Bookworm, editing
/etc/dhcpcd.confor dropping awpa_supplicant.confon the card does nothing. Current trixie images also include cloud-init and Netplan, which write the first-boot network settings. - Imager 1.x can't customise current trixie images. Raspberry Pi's Imager compatibility notes explain that an old Imager writes the settings in the wrong format, so the card boots with none of them applied: no user, no Wi-Fi, no SSH. Install Imager 2.x before you start.
If you're running Bookworm already, Raspberry Pi recommends moving to trixie with a fresh image on new media rather than an in-place upgrade (Raspberry Pi OS docs).
Hardware and supplies
- A Raspberry Pi 3, 4 or 5. For a few light services such as DNS filtering, a VPN endpoint or a monitoring agent, any of them works. The Pi 5 is the fastest and can boot from NVMe storage through its PCIe connector. For Docker with several containers, choose a model with 4 GB of RAM or more.
- The right power supply. The power supply docs recommend the 27 W USB-C supply (5 V, 5 A) for Raspberry Pi 5, the 3 A USB-C supply for Raspberry Pi 4 and the 2.5 A micro USB supply for Raspberry Pi 3. A Pi 5 on any supply that can't deliver 5 A limits its USB ports to 600 mA in total, which may not be enough for a USB SSD.
- A microSD card. At least 8 GB for Raspberry Pi OS Lite (32 GB for the desktop versions), and under 2 TB, the limit of the MBR partition table the Pi boots from. Faster cards make the whole system feel quicker.
- Another computer with an SD card reader to run Imager.
- An Ethernet cable if you can. A wired connection takes Wi-Fi settings out of the list of things that can go wrong on first boot.
A case is optional but protects the board from shorting on a metal surface. A headless server doesn't need the HDMI cable, keyboard or mouse that come with many kits.
Write the card with Raspberry Pi Imager
Install Imager from raspberrypi.com/software (Windows and macOS installers, or an AppImage for other Linux systems), or with sudo apt install rpi-imager on Raspberry Pi OS. Imager walks you through a series of tabs:
- Device: pick your Raspberry Pi model.
- OS: pick Raspberry Pi OS Lite (64-bit), the version without a desktop. The recommended OS for your model is at the top of the list; Lite versions are listed alongside the desktop ones.
- Storage: pick the SD card. Identify it by size, and if you're unsure, unplug other USB drives. Keep Exclude system drives turned on so Imager can't offer your computer's own disk.
- Customisation: opens for operating systems that support it. For a headless Pi, don't skip it.
Customisation settings
- Hostname: letters, numbers and hyphens only, for example
pi-server. The Pi announces it over mDNS, so other devices can reach it aspi-server.local(orpi-server.lanon some networks). - Localisation: choose your capital city. That sets the time zone, the keyboard layout and the Wi-Fi regulatory domain. On a Pi 3B+ or later, Wi-Fi stays disabled until the regulatory domain (WLAN country) is set, so this matters even for a headless Pi.
- User: a username (lowercase letters, numbers, underscores and hyphens) and a password. This password is also the one
sudoasks for. - Wi-Fi: Imager may pre-fill the network your computer is on. Check the network name, enter the password, and turn on Hidden SSID if your network doesn't broadcast its name. A headless Pi on Wi-Fi depends on this being right, because it has to get online by itself the moment it boots.
- Remote Access: turn on Enable SSH. If you already have an SSH key pair, choose Use public key authentication and paste or browse to your public key (the
.pubfile). Otherwise choose password authentication and switch to keys after the first login. - Raspberry Pi Connect: optional remote access through a Raspberry Pi ID account. You don't need it if you use SSH.
The Writing tab shows a summary. Select Write, confirm with I understand, erase and write, and let Imager verify the card afterwards. Verification takes a few extra minutes and catches bad cards before you start debugging the Pi.
On current trixie images, Imager stores your choices in files called user-data and network-config on the card's boot partition, which cloud-init applies at first boot (Raspberry Pi's cloud-init announcement describes both). If you notice a typo in the Wi-Fi password, you can fix it in network-config before the Pi's first boot. The files are YAML, so keep the indentation. They can contain your Wi-Fi password in plain text, so don't share the card or an image of it.
First boot and login
- Put the card in the Pi, connect Ethernet if you're using it, and plug in the power.
- Wait a few minutes. The first boot does extra setup work, such as applying your settings and expanding the filesystem.
- From your computer, check that the Pi answers, then log in with the username you set in Imager:
ping pi-server.local
ssh yourusername@pi-server.local
The first SSH connection asks you to confirm the Pi's host key fingerprint; answer yes. If .local names don't resolve on your network, use the IP address listed in your router's DHCP client table instead. The remote access docs list other ways to find it.
Check you got what you asked for:
hostnamectl # hostname, OS and kernel
grep VERSION_CODENAME /etc/os-release # should print VERSION_CODENAME=trixie
uname -m # aarch64 means the 64-bit OS
df -h / # root filesystem should fill most of the card
Raspberry Pi OS normally expands the root filesystem to fill the card on first boot. If df -h / shows only a few gigabytes on a large card, run sudo raspi-config, choose 6 Advanced Options → A1 Expand Filesystem, and reboot.
Bring it up to date
sudo apt update
sudo apt full-upgrade
sudo reboot
Raspberry Pi's update instructions use full-upgrade rather than plain upgrade, because Raspberry Pi OS changes package dependencies more often than Debian does. The kernel and stable firmware arrive the same way (the firmware is the raspi-firmware package), and the reboot loads them. If full-upgrade says it needs more space than you have, df -h shows what's free and sudo apt clean deletes downloaded package files.
Leave rpi-update alone unless a Raspberry Pi engineer asks you to use it: it installs pre-release kernel and firmware for testing, which the docs warn can make the system unbootable. If you've already run it, sudo apt install --reinstall raspi-firmware followed by a reboot returns to the stable firmware.
For the APT commands themselves, including what to do with kept-back packages, see Linux Package Management.
Give it an address that doesn't change
A server needs to be at the same address every time. Raspberry Pi's networking docs recommend a DHCP reservation (sometimes called a static lease) on your router: you tie the Pi's MAC address to an IP address, and all address management stays in one place. Find the MAC address with ip link show eth0 (or wlan0) on the Pi; it's the value after link/ether. Then reboot the Pi, or reconnect it, so it picks up the reserved address.
If you can't change the router, you can set a static address on the Pi with nmcli. The docs don't recommend it, because a mistake can cut the Pi off the network. Pick an address outside the router's DHCP pool that no other device uses, and do this from a local console or be ready to reconnect at the new address:
# Note the NAME of the connection on eth0 or wlan0
nmcli connection show
sudo nmcli connection modify "CONNECTION-NAME" \
ipv4.method manual \
ipv4.addresses 192.168.1.50/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "192.168.1.1"
sudo nmcli connection up "CONNECTION-NAME"
Replace the addresses with ones from your own network. On images configured by Imager 2, connection names start with netplan-. Raspberry Pi's cloud-init announcement explains that NetworkManager writes changes to those connections back into Netplan's configuration, so a change made with nmcli persists across reboots.
Check it worked: nmcli device show eth0 | grep IP4 lists the address, gateway and DNS server in use, and ping -c 3 debian.org confirms that routing and name resolution both work.
Switch SSH to keys only
Skip the first step if you gave Imager a public key. Otherwise, on your own computer, create a key pair if you don't have one and copy the public key to the Pi:
ssh-keygen -t ed25519
ssh-copy-id yourusername@pi-server.local
Windows includes the OpenSSH client but not ssh-copy-id. In PowerShell, run ssh-keygen -t ed25519, then:
Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" | ssh yourusername@pi-server.local "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Log out and back in. If you're no longer asked for the account password (you may be asked for the key's passphrase instead), the key works. Now turn off password logins with a drop-in file, test the configuration, and restart SSH. Keep your current session open until a new login has worked:
echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/10-no-passwords.conf
sudo sshd -t
sudo systemctl restart ssh
# Should print: passwordauthentication no
sudo sshd -T | grep -i passwordauthentication
sshd uses the first value it reads for each setting, and reads the files in /etc/ssh/sshd_config.d/ in name order, so a file whose name sorts earlier can override yours. If the last command still prints yes, sudo grep -ri passwordauthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ finds where it's set.
Check it from a second terminal on your computer: ssh -o PubkeyAuthentication=no yourusername@pi-server.local should now be refused with Permission denied (publickey), which shows the Pi no longer offers password logins. A normal ssh yourusername@pi-server.local should still work. Locking Down SSH covers the other settings worth changing and Fail2Ban.
Add a firewall
sudo apt install ufw
sudo ufw allow ssh # allow SSH before enabling, or you lock yourself out
sudo ufw enable
sudo ufw status verbose
The status should show Status: active, incoming traffic denied by default, and a rule allowing port 22. Add a rule for each service you install later, for example sudo ufw allow 53 for a DNS server. If you run Docker, Docker's documentation warns that ports published by containers bypass ufw rules, so treat every published port as open to your network.
SD card or SSD?
SD cards wear out under constant writes and cheap ones are slow. For a Pi that writes a lot (databases, logs, Docker images), boot from a USB SSD, or on a Pi 5 from NVMe storage. Raspberry Pi 4 and later can boot from USB mass storage; the order the bootloader tries devices in is covered in the Raspberry Pi hardware docs. Imager writes to an SSD in a USB enclosure the same way it writes an SD card. More than one USB disk usually needs a powered hub or enclosures with their own power.
Docker on a Pi
On 64-bit Raspberry Pi OS (dpkg --print-architecture prints arm64), install Docker Engine using Docker's instructions for Debian; the Docker Installation Guide walks through them. Docker's Raspberry Pi OS page says Docker Engine v28 is the last major version with packages for 32-bit Raspberry Pi OS, and that ARMv6 boards (Raspberry Pi 1, Zero and Zero W) aren't supported by the official packages at all.
# Let your user run docker without sudo, then log out and back in
sudo usermod -aG docker $USER
docker run hello-world
hello-world prints Hello from Docker! if the engine can pull and run images. Being in the docker group is equivalent to having root on the Pi, so only add accounts you'd trust with root. Most popular images publish arm64 builds, but check an image's tags before planning around it.
Things a Pi handles well include Pi-hole or AdGuard Home, a WireGuard endpoint, Home Assistant and monitoring agents. Nextcloud and media servers work for a few users, better from an SSD than an SD card; video transcoding is where Pi hardware runs out.
Automatic security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
# See what it would install, and which origins it allows, without changing anything
sudo unattended-upgrade --dry-run --debug
unattended-upgrades only installs packages from the origins listed in /etc/apt/apt.conf.d/50unattended-upgrades, and the debug output prints that list. Raspberry Pi's own repository, which carries the kernel and firmware, identifies itself as Raspberry Pi Foundation; if that origin isn't in the list, those packages still need a manual sudo apt full-upgrade. It doesn't reboot unless you set Unattended-Upgrade::Automatic-Reboot in the same file, so plan a reboot after kernel updates.
When something goes wrong
The Pi doesn't boot
If the green activity LED never flickers, re-write the card with Imager (with verification on), try a different card, and check the power supply. The configuration docs describe the LED blink patterns the bootloader uses for specific faults.
It boots but never appears on the network
- Settings not applied at all: if the card was written with Imager 1.x, the trixie image ignores the customisation. Update Imager to 2.x and write it again.
- Wi-Fi: check the network name, password and capital city (WLAN country) you set. Before the first boot you can correct them in
network-configon the boot partition. After that, connect Ethernet or a screen and keyboard and runnmcli radio wifi, which should printenabled, thensudo nmcli --ask dev wifi connect "NETWORK-NAME". - Finding it: look in the router's DHCP client list, or scan your subnet from another Linux machine with
nmap -sn 192.168.1.0/24(use your own network range).
SSH errors
Permission denied: use the username you created in Imager; there is nopiaccount. If you chose key authentication, the matching private key has to be on the computer you're connecting from.Connection refused: SSH wasn't enabled. Write the card again with Enable SSH on, or with a screen attached, runsudo raspi-configand enable SSH under Interface Options.REMOTE HOST IDENTIFICATION HAS CHANGEDafter re-writing the card: a fresh image generates new host keys, and your computer remembers the old ones. If you've just re-imaged this Pi, remove the old entry withssh-keygen -R pi-server.local(and again with the IP address if you connected by IP). If you haven't, don't remove it until you know why the key changed.
Random crashes or a corrupted card
Power is the usual cause. Check whether the Pi has seen under-voltage or throttling since boot:
vcgencmd get_throttled
throttled=0x0 means none of the conditions has been detected. Any other value has bits set for under-voltage, ARM frequency capping, throttling or the soft temperature limit, either happening now or at some point since boot; man vcgencmd lists what each bit means. The fix is usually the official supply for your model, or one with the same voltage and current rating, rather than a phone charger, plus a short cable. Pulling the power while the system is writing can also corrupt the card, so shut down with sudo poweroff and wait for the activity LED to stop before unplugging.
It's slow
vcgencmd measure_temp shows the SoC temperature. According to Raspberry Pi's hardware docs, the CPU is throttled progressively between 80°C and 85°C, and at 85°C the GPU is throttled too. Throttling prevents damage on its own, but a heatsink or fan reduces how often it happens. If the temperature is fine, look at storage: a slow SD card slows everything, and an SSD helps most.
Clean up and retire
After testing, remove what you don't need on the Pi:
# Remove the hello-world test container and image (if you ran it)
docker ps -aq --filter ancestor=hello-world | xargs -r docker rm
docker image rm hello-world
# Remove unused dependencies and cached package files
sudo apt autoremove
sudo apt clean
When you retire or re-purpose a Pi, also remove its DHCP reservation and firewall rules on the router, delete its entry from your computer's known_hosts with ssh-keygen -R pi-server.local, and remove the device from your Raspberry Pi Connect account if you enabled it. The card can hold account details, SSH keys and Wi-Fi passwords. Re-imaging prepares it for reuse but is not secure erasure: old blocks may remain recoverable, especially on flash media. Revoke stored credentials and keep or physically destroy a sensitive card; only rely on a device-supported sanitization procedure when you can verify its guarantees.
What to set up next
- Pi-hole Deployment Guide: network-wide DNS filtering, a common first job for a Pi server.
- WireGuard-Easy Deployment: a VPN for reaching your home network from outside.
- RaspAP Wireless Access Point: turning the Pi into a Wi-Fi access point or travel router.
- Locking Down SSH: the rest of the SSH hardening, including Fail2Ban.
- The Complete Self-Hosting Guide for 2026: planning backups, power and remote access when one Pi becomes several services.



