In short
- A good Raspberry Pi 5 home server setup starts with the 64-bit Raspberry Pi OS on an SSD, Docker from Docker's own apt repository, and a few light services: Pi-hole for network-wide ad blocking, Uptime Kuma to watch everything else, and Vaultwarden once you have HTTPS.
- That starter stack fits comfortably on a 4GB Pi 5.
- Save the 8GB board for the heavy apps: Immich is the one whose documented requirements actually need it.
Contents10 sections
- Prerequisites
- Step 1: flash the 64-bit OS with Imager
- Step 2: update, and optionally boot from NVMe
- Step 3: install Docker from Docker's repository
- Step 4: add Pi-hole
- Step 5: add Uptime Kuma
- Step 6: add a reverse proxy, then Vaultwarden
- 4GB or 8GB? What the documentation supports
- Troubleshooting (documented issues only)
- What to do next
This guide keeps its RAM advice conservative. Every figure comes from a project's own documentation, and where a project publishes no figure, the guide says so rather than guessing.
Prerequisites
- A Raspberry Pi 5. The April 2026 product brief lists five RAM options and their list prices: 1GB ($45), 2GB ($65), 4GB ($110), 8GB ($175) and 16GB ($305). Prices change, so treat these as a snapshot.
- The right power supply. Raspberry Pi recommends its 27W USB-C supply for the Pi 5. This matters on a server: the power-supply docs say the Pi 5 gives USB peripherals 1.6A only on a supply capable of 5A at 5V. On any other compatible supply, it limits them to 600mA. A USB SSD may need more than that.
- Storage that isn't just the SD card. Either an NVMe SSD on the M.2 HAT+ (the Pi 5 has a PCIe 2.0 x1 interface), or a USB 3 SSD. Immich and PhotoPrism both say their databases belong on local SSD storage.
- Wired Ethernet (the Pi 5 has gigabit) and a DHCP reservation for the Pi. Pi-hole's prerequisites say it "needs a static IP address to properly function", and that a DHCP reservation "is just fine".
Step 1: flash the 64-bit OS with Imager
Use Raspberry Pi Imager and pick Raspberry Pi OS (64-bit). The Lite edition is enough for a headless server. The official install guide strongly recommends the Customisation step. There you set:
- a hostname
- your username and password, which a headless setup uses to log in over the network
- your locale
- SSH, switched on under Remote Access
Why 64-bit, specifically: Docker's documentation says Engine v28 is the last major version for 32-bit Raspberry Pi OS (armhf). From v29, new major versions ship no 32-bit Pi OS packages. The 64-bit OS uses Docker's Debian arm64 packages, which Docker calls "fully supported". Several apps (Immich, Jellyfin, Audiobookshelf) only publish arm64 images for ARM anyway.
Boot the Pi and SSH in with the username you set.
Step 2: update, and optionally boot from NVMe
Raspberry Pi's NVMe boot guide starts with a full update:
sudo apt update && sudo apt full-upgradeIf you fitted an NVMe drive, check that the Pi sees it:
ls -l /dev/nvme*What you should see: device entries like /dev/nvme0 and /dev/nvme0n1, as in the docs' example output.
Then set the boot order:
sudo raspi-configUnder Advanced Options → Boot Order, pick an option that includes NVMe, then Finish and reboot. The docs say the Pi then uses the new boot order. The NVMe drive needs an OS on it before the Pi can boot from it.
Step 3: install Docker from Docker's repository
Docker's Pi page sends 64-bit Pi OS users to the Debian instructions. Those are:
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginCheck it:
sudo docker run hello-worldWhat you should see: the hello-world container prints its confirmation message and exits.
Docker also offers a get.docker.com convenience script. Its own docs say the script "isn't recommended for production environments" and isn't designed to upgrade an existing install, so the repository route is the better base for a server you'll keep.
To run docker without sudo, follow the post-install steps:
sudo groupadd docker
sudo usermod -aG docker $USERLog out and back in. Docker's docs warn that the docker group "grants root-level privileges to the user", so add only your own admin account.
One firewall caveat from Docker's install page: if you use ufw or firewalld, ports you publish from containers bypass your firewall rules. Don't assume a ufw rule is protecting a container.
Step 4: add Pi-hole
Pi-hole's own requirements are small: 512MB of RAM and at least 2GB of free disk (4GB recommended). Make a folder and save this as compose.yaml. It's the README's example with two changes, marked in the comments:
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp" # changed from 80:80, so a reverse proxy can have port 80
- "8443:443/tcp" # changed from 443:443, for the same reason
environment:
TZ: 'Europe/London'
FTLCONF_webserver_api_password: 'correct horse battery staple'
FTLCONF_dns_listeningMode: 'ALL'
volumes:
- './etc-pihole:/etc/pihole'
cap_add:
- NET_ADMIN
- SYS_TIME
- SYS_NICE
restart: unless-stoppedThe port changes follow Pi-hole's Docker tips page, which gives exactly this remap ("80:80/tcp" to "8080:80/tcp") for when ports 80 and 443 are taken. On a home server they soon will be, by the reverse proxy in step 6. DNS on port 53 can't move. Also set TZ to your own timezone and replace the example password. The README's comments explain FTLCONF_dns_listeningMode: 'ALL', which is needed on Docker's default bridge network, and the three capabilities. NET_ADMIN is only required if Pi-hole is also your DHCP server.
docker compose up -dWhat you should see: the admin page at http://<pi-ip>:8080/admin/. Then point your router's DNS setting at the Pi. The full walkthrough, including the AdGuard Home option, is in network-wide ad blocking with Pi-hole or AdGuard Home.
Step 5: add Uptime Kuma
From the Uptime Kuma README:
mkdir uptime-kuma
cd uptime-kuma
curl -o compose.yaml https://raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
docker compose up -dWhat you should see: per the README, Uptime Kuma on http://your-ip:3001. Keep its data on the Pi's local disk: the README says NFS and other network file systems "are NOT supported". Add a monitor for the Pi-hole admin page to start with. More in monitor websites for free with Uptime Kuma.
Step 6: add a reverse proxy, then Vaultwarden
Vaultwarden's web vault only works over HTTPS, so put a reverse proxy in place first. Reverse proxy for a homelab: Caddy or Nginx Proxy Manager covers both options, and both publish arm64 images. Then follow how to self-host Vaultwarden on a Raspberry Pi.
4GB or 8GB? What the documentation supports
Here's what each project publishes, and where that leaves the two most common Pi 5 sizes:
| App | Documented requirement | 4GB Pi 5 | 8GB Pi 5 |
|---|---|---|---|
| Pi-hole | 512MB RAM, 2GB disk min | Yes | Yes |
| Uptime Kuma | No RAM figure published; arm64 image | Yes, with no official figure | Yes |
| Vaultwarden | No RAM figure; README pitches it for where the official server is "resource-heavy" | Yes, with no official figure | Yes |
| Nextcloud | 128MB per PHP process min, 512MB recommended; totals "greatly variable" | Small household, few extra apps | More room for Office and Talk |
| Seafile CE | 2GB RAM, 2 cores | Yes | Yes |
| PhotoPrism | Pi guide: Pi 4 or 5 with 4GB+, plus 4GB swap | Yes | Yes |
| Immich | 6GB min, 8GB recommended; 4GB only with machine learning disabled | Only with ML off | Meets the recommendation |
| Jellyfin | Pi hardware acceleration deprecated; the Pi 5 "lacks hardware encoders entirely" | Direct play only | Direct play only |
How to read it conservatively:
- The published figures are per app, not per stack. No project says what its app needs next to four others. On a 4GB Pi, pick one heavy app (Nextcloud, PhotoPrism or Seafile) on top of the light ones, not all three.
- Immich is the clearest 8GB case. Its docs say "at least 6GB" for a smooth experience, especially during uploads. On 4GB you lose machine learning, which means no face recognition and no smart search. If you use Docker memory limits, its Postgres container alone needs at least 2GB.
- For Nextcloud, the 4GB/8GB split in the table is a judgement from the per-process figures, not a number Nextcloud publishes. The same judgement appears on the Nextcloud profile.
- Video transcoding isn't a RAM problem. Jellyfin deprecated Raspberry Pi acceleration after the Pi 5 shipped without hardware encoders, so more RAM won't fix it. See the Jellyfin profile.
Troubleshooting (documented issues only)
- Pi-hole won't start: port 53 in use. The Pi-hole docs say systemd-resolved, the default on Ubuntu 17.10+ and Fedora 33+, holds port 53, and they describe how to disable its stub listener. Raspberry Pi OS isn't on their list, but it applies if you run Ubuntu on the Pi. More generally, their advice for port conflicts is to stop the existing DNS or web service and stop it auto-starting.
- Pi-hole web page conflicts with another service. Remap the web ports as in step 4.
- A USB SSD disconnects or won't power up. Check the power supply. Below a 5A supply, the Pi 5 caps USB peripherals at 600mA. The docs' alternative is an externally powered USB hub.
dockersays permission denied. You haven't logged out and back in since joining thedockergroup. Docker's docs also offernewgrp dockerto apply it straight away.- Uptime Kuma data errors on a NAS mount. Network file systems aren't supported. Use a local directory.
- Docker packages missing on a 32-bit OS. Reflash with the 64-bit image (step 1).
What to do next
- Pick more apps by RAM in the best self-hosted apps for a Raspberry Pi.
- Choose your ad blocker with Pi-hole vs AdGuard Home.
- Add file sync with the Nextcloud Docker Compose guide. The images it uses publish arm64 builds.
- Outgrowing the Pi, or want a public-facing piece off your home network? See the VPS guide for self-hosting.
Sources (18)ShowHide
- Raspberry Pi 5 product brief (published April 2026) · accessed 2026-09-29
- Raspberry Pi documentation: Power supplies (source on GitHub) · accessed 2026-09-29
- Raspberry Pi documentation: NVMe SSD boot (source on GitHub) · accessed 2026-09-29
- Raspberry Pi documentation: Install an operating system (Imager customisation; source on GitHub) · accessed 2026-09-29
- Docker docs: Install Docker Engine on Raspberry Pi OS (32-bit / armhf) — 64-bit users follow Debian · accessed 2026-09-29
- Docker docs: Install Docker Engine on Debian · accessed 2026-09-29
- Docker docs: Linux post-installation steps · accessed 2026-09-29
- docker-pi-hole README (compose example) · accessed 2026-09-29
- Pi-hole docs: Prerequisites · accessed 2026-09-29
- Pi-hole docs: Docker tips and tricks (port conflicts) · accessed 2026-09-29
- Uptime Kuma README and compose.yaml · accessed 2026-09-29
- Vaultwarden README · accessed 2026-09-29
- Seafile Admin Manual: System requirements (via the Raspberry Pi best-apps page) · accessed 2026-09-29
- PhotoPrism: Running on a Raspberry Pi (via the Raspberry Pi best-apps page) · accessed 2026-09-29
- Docker Hub image architectures (arm64-only images for Immich, Jellyfin, Audiobookshelf; via the Raspberry Pi best-apps page) · accessed 2026-09-29
- Immich: Requirements · accessed 2026-09-29
- Nextcloud 35 Administration Manual: System requirements · accessed 2026-09-29
- Jellyfin: Hardware Acceleration (Raspberry Pi support deprecation) · accessed 2026-09-29