Getting started
What this Pi does
UniFi controller on Raspberry Pi 5 is a solid way to manage a few access points and a switch without buying a bigger box. The Pi sits on Ethernet, keeps a fixed IP from a DHCP reservation, and hosts the UniFi Network Application. Storage matters: microSD works, but an SSD handles database writes better. A UPS helps too. Keep the clock synced with NTP so logins and certificates behave.
What to lock in
Adoption usually “just works” on one LAN, but VLANs may need TCP 8443 and 8080 plus UDP 3478 and 10001 opened. Set automatic .unf backups, and the rebuild is painless. Pick Docker Compose or a systemd service, then keep updates boring.
Key takeaways
- Put the controller on Ethernet with a stable IP.
- SSD beats microSD for long-term reliability.
- Back up before every UniFi update.
- Update controller first, devices second.
- If VLANs are involved, inform traffic matters more than discovery.
- Don’t expose the controller UI to the internet.
Hardware + OS prep
Hardware checklist (small controller, low drama)
- Raspberry Pi 5 (4GB is fine for a small site, 8GB gives more headroom)
- Official USB-C power supply (or a known-good 5V PSU that won’t sag under load)
- Active cooling (Pi 5 runs warm, and heat causes slowdowns)
- Ethernet cable to your switch or router
- Storage: microSD for boot, plus SSD for UniFi data if you can swing it
Storage choice (this is where people get burned)
UniFi writes a steady stream of stats and events. microSD cards can handle it for a while, then they get flaky.
A simple rule:
- microSD only: OK for a tiny setup, but plan for failure
- SSD: better long-term, fewer weird crashes, faster restores
If using an SSD, put your UniFi data and backups on the SSD. Keep the microSD for the OS if that’s the easiest path.
Cooling + power checks
- Put the Pi 5 in a case with airflow.
- Enable the fan profile if your cooler supports it.
- If the controller “randomly” restarts, suspect power before anything else.
Install Raspberry Pi OS (64-bit)
- Use Raspberry Pi Imager.
- Pick Raspberry Pi OS (64-bit).
- Set these in the Imager options:
- hostname (example:
unifi-pi5) - enable SSH
- username + strong password
- Wi-Fi only if Ethernet is impossible (Ethernet is the better call)
- hostname (example:
After first boot, update packages:
sudo apt update && sudo apt -y upgrade
sudo reboot
Give it a stable address
UniFi device adoption likes a controller that stays put.
Two clean options:
- DHCP reservation on the router (best for most people)
- Static IP on the Pi (fine, but make sure it’s outside the DHCP pool)
Also set a DNS name if you can (example: unifi-pi5.lan). It makes “set-inform” and bookmarks less annoying.
Set time and basics
- Set your time zone.
- Make sure NTP is running.
- Check disk space before you install UniFi.
Quick checks:
hostnamectl
timedatectl
df -h
ip addr
Quick “is this ready?” checklist
- SSH works
- Pi is on Ethernet
- IP address won’t change
- Storage has room (and SSD is mounted if you’re using one)
- Pi stays cool under load
Install option A: Docker (clean setup, easy recovery)
Why this path works well on a Pi 5
Docker keeps UniFi in its own container, so the Pi stays tidy. If an update acts up, switching image tags back is usually faster than wrestling with a broken package install.
1) Install Docker (Pi OS 64-bit)
Raspberry Pi OS 64-bit is basically Debian arm64, so the Debian install steps apply.
Use Docker’s Debian method, then confirm it runs:
docker --version
docker compose version
Optional, but most people do it: let your normal user run Docker without sudo.
2) Create folders for UniFi data
Put UniFi data on the SSD if you have one. If not, keep it on the main filesystem.
sudo mkdir -p /srv/unifi/{config,data,logs}
sudo chown -R $USER:$USER /srv/unifi
3) Use a Compose file
Create /srv/unifi/compose.yml:
services:
unifi-network-application:
image: lscr.io/linuxserver/unifi-network-application:latest
container_name: unifi-network-application
environment:
- PUID=1000
- PGID=1000
- TZ=America/Chicago
volumes:
- /srv/unifi/config:/config
ports:
- "8443:8443" # Web UI
- "8080:8080" # Device inform
- "3478:3478/udp" # STUN
- "10001:10001/udp" # Discovery
restart: unless-stopped
Those ports line up with what UniFi and the LinuxServer image document as the common baseline.
4) Start it and make sure it stays up
cd /srv/unifi
docker compose up -d
docker ps
Then open the UI from your LAN:
https://<pi-ip>:8443
5) Ports: what you actually need (most home and small office setups)
| Purpose | Protocol | Port |
|---|---|---|
| Controller web UI | TCP | 8443 |
| Device inform | TCP | 8080 |
| Adoption assist (STUN) | UDP | 3478 |
| Discovery | UDP | 10001 |
If you use guest portal features, there are extra ports, but plenty of small setups never touch them.
6) Quick sanity checks
docker logs -n 50 unifi-network-application
ss -tulpn | grep -E '8443|8080|3478|10001'
Small-but-important warning
- Don’t port-forward 8443 from the internet. Keep the controller on your LAN.
Install option B: Native APT install (closer to “official,” also a bit spicier)
When this is the right call
If you want UniFi Network Application to run like a normal Linux service, and you don’t feel like babysitting container files, this is your lane. Spoiler alert, updates can still surprise you, so backups happen first.
Back up before touching anything
In the UniFi UI: Settings → System → Backups, grab a manual backup file (*.unf).
Install using Ubiquiti’s APT steps
These are the exact building blocks Ubiquiti documents for Debian or Ubuntu style installs. On Raspberry Pi OS 64-bit, the flow is similar.
Run the required packages command:
sudo apt-get update && sudo apt-get install -y ca-certificates apt-transport-https
Add the UniFi repo list entry:
echo 'deb [ arch=amd64,arm64 ] https://www.ui.com/downloads/unifi/debian stable ubiquiti' | sudo tee /etc/apt/sources.list.d/100-ubnt-unifi.list
Add the repo key (Ubiquiti’s recommended method):
sudo wget -O /etc/apt/trusted.gpg.d/unifi-repo.gpg https://dl.ui.com/unifi/unifi-repo.gpg
Install UniFi:
sudo apt-get update && sudo apt-get install -y unifi
If the service doesn’t start on its own:
sudo service unifi start
Ubiquiti also lists handy service commands like stop, restart, and status.
MongoDB note (don’t ignore it)
Ubiquiti’s guide calls out MongoDB handling, and when to skip it depending on what version you’re installing or upgrading from. If you’re doing a fresh install and UniFi won’t come up cleanly, this is one of the first places to look.
Confirm the controller is reachable
From a browser on your LAN:
https://<pi-ip>:8443
Then confirm the ports are listening:
ss -tulpn | grep -E '8443|8080|3478|10001'
Those ports show up in Ubiquiti’s ports reference (and you’ll care even more if VLANs are involved).
Where logs live (when things get weird)
If the service acts up, Ubiquiti lists log paths like:
/usr/lib/unifi/logs/server.log/usr/lib/unifi/logs/mongod.log
First login + baseline settings
Now, before the clicking starts, the goal here is simple. Get in, set the boring basics, and avoid the usual “why is this acting weird” later.
Open the controller
- In a browser on the same LAN, go to
https://<pi-ip>:8443 - If a browser warning shows up, that’s normal for a fresh controller cert
- Local access only works when the device running UniFi is on the same local network, unless Remote Management is set up.
Pick the sign-in style
- Local-only access: stays on your LAN, fewer moving parts
- UI Account with Remote Management: handy if managing from elsewhere, but lock it down with MFA.
Baseline settings to set right away
- Timezone and country: match the real location so logs and Wi-Fi rules line up
- Controller name and site name: make it obvious later when there’s more than one site
- Auto backup: turn it on and set a schedule so a rebuild is not a weekend-killer.
- Stats retention: keep it modest on a Pi so storage does not balloon (Auto or shorter windows usually behaves better on small storage).
Security settings that pay off
- If Remote Management is enabled, add MFA on the UI Account, then store recovery codes somewhere safe.
- Keep the controller UI off the open internet. If remote access is needed, use UniFi’s Remote Management instead of port forwarding.
Quick checklist before adopting devices
| Check | What “good” looks like |
|---|---|
| Web UI loads | https://<pi-ip>:8443 works on LAN |
| Auto backup enabled | Backup schedule is set in System settings |
| Adoption ports reachable | LAN firewalls allow UniFi ports as needed |
Adopt UniFi devices and fix the usual adoption nonsense
Before you click anything
- Put the Raspberry Pi 5 controller on Ethernet.
- Make sure the controller has a stable IP (DHCP reservation is fine).
- If the device was used before, expect it to “remember” an old controller and act stubborn.
Fast path: same LAN adoption
- Plug in the UniFi AP or switch.
- Wait 1 to 3 minutes.
- In the UniFi UI, look for the device under Devices with a status like Pending Adoption.
- Click Adopt.
- Let it finish provisioning. Don’t power-cycle it halfway through unless you like chaos.
If it was adopted to another controller earlier
- In the UniFi UI (old controller), use Forget if you still have access.
- If you don’t, do a factory reset on the device, then try adoption again.
Cross-VLAN adoption
This is where people waste an afternoon.
Discovery (the “it just shows up” part) often fails across subnets. So you do one of these:
- Temporarily place the device on the same VLAN as the controller for adoption, then move it back.
- Keep it on its VLAN and use set-inform, plus allow the needed traffic between VLANs.
Ports you should allow (device VLAN to controller IP)
| What it’s for | Protocol | Port |
|---|---|---|
| Device inform (adoption + ongoing) | TCP | 8080 |
| STUN (helps with NAT behavior) | UDP | 3478 |
| Discovery (usually same LAN only) | UDP | 10001 |
| Controller web UI (your browser to controller) | TCP | 8443 |
If you only do one thing right, allow TCP 8080 from the device network to the controller IP.
Set-inform fallback (works when discovery doesn’t)
- SSH into the UniFi device (AP or switch).
- Run this command, swapping in your controller IP:
set-inform http://<controller-ip>:8080/inform - Go back to the UniFi UI and click Adopt.
- Run the same
set-informcommand one more time if it asks again (some devices do).
Quick fixes by symptom
| Symptom you see | What it usually means | What you do |
|---|---|---|
| Device never appears | Discovery blocked, wrong VLAN, or it’s not reset | Try same VLAN once, then set-inform |
| Stuck on “Adopting” | Inform can’t reach controller | Check TCP 8080 rules to controller IP |
| Adopts, then “Disconnected” | Bad IP, DNS, or firewall rules | Confirm controller IP did not change, recheck rules |
| Says “Managed by other” | It’s still tied to another controller | Factory reset, then adopt again |
Backups + restores (so a bad update or dead card doesn’t ruin your week)
Here’s the truth: storage fails. Updates happen. A controller rebuild should take minutes, not a full-blown rage spiral.
Set up automatic backups
In the UniFi controller UI:
- Go to Settings → System → Backups
- Turn on Automatic backups
- Set a schedule (daily is fine for most small setups)
- Keep a reasonable retention count (example: 7–14 backups)
Tip that saves pain: store backups somewhere not on the same drive as the controller data when possible.
Also take manual backups before changes
Do a manual backup before:
- UniFi version upgrades
- Major network changes (new VLANs, SSIDs, firewall rules)
- Moving the controller to new hardware
Name the file with the date so you can spot it later.
If you’re on Docker
What to protect:
- Your UniFi /config volume (that’s where the controller state lives)
- Your UniFi backup exports (downloaded files)
Simple habit that works:
- Keep
/srv/unifi/configon an SSD - Copy that folder (or at least the UniFi backup exports) to another machine occasionally
If you’re on native install
Your backups are still handled inside the UniFi UI the same way. The big risk is the underlying storage (microSD/SSD) and unexpected service issues during upgrades.
How to restore after a rebuild
You’ve got two common restore situations:
A) Same controller name/IP, fresh install
- Install UniFi again (Docker or native)
- Open the UI
- Choose Restore from backup
- Upload the backup file
- Wait for it to come back up
- Confirm devices reconnect (they usually do if IP/hostname stayed the same)
B) New controller IP/hostname
This can be fine, but devices may still “phone home” to the old controller address.
- Best move: keep the controller IP the same using DHCP reservation
- If you must change it, be ready to run
set-informagain on any stubborn devices
Restore validation (don’t skip this)
After a restore, confirm:
- SSIDs are present and enabled
- VLAN networks exist
- Devices show up and come online
- Guest networks and DNS settings behave
- Alerts aren’t screaming about “Adoption failed” or “Disconnected”
Mini survival checklist
- Auto backups on
- Manual backup before updates
- Controller IP stable
- Backups copied off-device sometimes
- SSD preferred over microSD for long-term sanity
Updates without breaking things + fast troubleshooting when it does
You don’t need “latest.” You need stable. The fastest way to wreck a small Pi controller is updating blindly, then realizing the controller won’t start and the house Wi-Fi looks like it’s possessed.
Update rules that keep this boring
- Back up first (manual backup in the UI, every time).
- Don’t update UniFi and your devices at the same time.
Update the controller, confirm it’s healthy, then update APs/switches after. - Avoid “auto-updating” the controller unless you enjoy surprise downtime.
- Keep the controller IP the same (DHCP reservation). A changed IP is a sneaky adoption killer.
Docker update flow (safe and reversible)
What to do
- Back up in the UI.
- Edit your
compose.ymlto pin a version tag (instead oflatest). - Pull and restart:
cd /srv/unifi docker compose pull docker compose up -d
Health checks
docker ps
docker logs -n 80 unifi-network-application
If the update acts up
- Roll back by restoring the previous image tag and restarting.
- If it’s still messy, restore the backup file in the UI.
Native update flow (more “traditional,” more risk)
What to do
- Back up in the UI.
- Update packages:
sudo apt update sudo apt -y upgrade sudo reboot - Confirm the UniFi service:
sudo service unifi status
If it won’t start
sudo service unifi restart
sudo journalctl -u unifi --no-pager -n 120
Troubleshooting: fix by symptom (quick and ruthless)
Controller web UI won’t load
Checks
- Is the Pi reachable?
ping <pi-ip> - Is the port listening?
ss -tulpn | grep 8443 - Docker?
docker ps
Common causes
- Service/container not running
- Wrong IP (DHCP changed)
- Firewall blocking 8443 on your LAN
- Browser caching a stale cert warning page (try another browser)
Devices won’t adopt
Most common cause: inform traffic can’t reach the controller.
Checks
- Controller has stable IP.
- VLAN rules allow device VLAN → controller IP on TCP 8080.
Fix
- Use
set-informfrom the device:set-inform http://<controller-ip>:8080/inform - If it says it’s managed elsewhere, factory reset the device first.
Devices adopt, then go “Disconnected”
Common causes
- Controller IP changed
- Firewall rule is too strict (allows adoption but blocks ongoing inform)
- Network loop or unstable uplink
Fixes
- Lock the controller IP.
- Confirm TCP 8080 stays allowed.
- Check switch port/VLAN tagging is correct for that device.
Controller is running but feels slow
Usual culprits
- microSD wear or low free space
- CPU throttling due to heat
- Too much stats retention for a small box
Checks
df -h
vcgencmd measure_temp 2>/dev/null || true
top
Fixes
- Move UniFi data to SSD.
- Improve cooling.
- Lower retention.
“Nuclear option” recovery (fast rebuild)
If you’re stuck in a loop:
- Fresh install UniFi (same method as before).
- Keep the same controller IP if possible.
- Restore from your most recent backup file.
- If a few devices still resist,
set-informthem to the new controller.
Security hardening for a LAN-only UniFi controller
Keep the UI off the public internet
- Don’t port-forward 8443 from your router.
- If remote access is needed, use a VPN into your home network, not an exposed admin page.
Lock down SSH (this is the big one)
- Use SSH keys, then disable password login.
- Limit SSH to your LAN only.
Quick path (Pi OS):
# Create a key on your computer (if you don't have one)
ssh-keygen
# Copy key to the Pi
ssh-copy-id <user>@<pi-ip>
# Edit SSH settings on the Pi
sudo nano /etc/ssh/sshd_config
Change or confirm these lines:
PasswordAuthentication noPermitRootLogin no
Restart SSH:
sudo systemctl restart ssh
Add a simple firewall rule set
If you don’t have a firewall on the Pi, add one. Keep it boring: allow only what you use, from only your local subnets.
Example with ufw:
sudo apt -y install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
# SSH from your LAN subnet (example 192.168.1.0/24)
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
# UniFi UI for your browser
sudo ufw allow from 192.168.1.0/24 to any port 8443 proto tcp
# UniFi device inform
sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp
# UniFi STUN + discovery (usually LAN only)
sudo ufw allow from 192.168.1.0/24 to any port 3478 proto udp
sudo ufw allow from 192.168.1.0/24 to any port 10001 proto udp
sudo ufw enable
sudo ufw status verbose
If you have VLANs, swap 192.168.1.0/24 for the actual device subnets that should reach the controller.
Harden the controller login
- Use a strong admin password.
- Turn on MFA if you use a cloud sign-in.
- Don’t create extra admin accounts “just in case.” That’s how old logins stick around forever.
Protect the controller’s storage
- Prefer SSD for UniFi data.
- If you’re stuck on microSD, keep backups off the Pi, because that card will eventually tap out.
Simple maintenance checklist
Weekly
- Manual backup download (even if auto backups are on).
- Quick health glance:
df -h free -h uptime
Monthly
- OS updates:
sudo apt update && sudo apt -y upgrade sudo reboot - Check temps and throttling signs:
vcgencmd measure_temp 2>/dev/null || true - Check that the controller still has the same IP:
hostname -I
Before any UniFi update
- Download a manual backup.
- Update the controller first.
- Confirm devices reconnect.
- Update APs and switches after.
Red flags that mean “fix it now”
- Disk free space under 20 percent
- Random reboots (power or heat)
- Devices flapping between Online and Disconnected
- Controller UI slow after days of uptime (usually storage or heat)
FAQ
Will Wi-Fi stop if the controller goes offline?
No. Your UniFi access points keep broadcasting SSIDs and handing out connections. What you lose is the “brain stuff”: stats, alerts, and making changes in the UI until the controller is back.
Do UniFi devices need the controller running 24/7?
Not for basic Wi-Fi and switching. But if you want guest portal features, logging, alerts, and quick changes, keeping it up all the time is the whole point.
Is a Raspberry Pi 5 strong enough?
For a small setup, yes: a few APs and a switch is fine. The limit is usually storage and heat, not raw CPU. If the UI feels slow, SSD + cooling fixes more than “more RAM” does.
Is microSD okay?
It works, but it’s the weakest link. UniFi writes stats and events constantly, and microSD wears out. For “set it and forget it,” put UniFi data on an SSD.
Can the controller live on a different VLAN than the APs?
Yes, but you must allow the right traffic from the device VLANs to the controller IP. If discovery fails, set-inform works across VLANs as long as inform traffic is allowed.
What are the minimum ports to allow?
Most small setups only need:
- TCP 8443 (you → controller UI)
- TCP 8080 (devices → controller inform)
Often also: - UDP 3478 (STUN)
- UDP 10001 (discovery, mostly same LAN)
What’s the easiest “it broke” recovery?
Reinstall UniFi (same method), keep the same controller IP if possible, restore from the latest backup, then set-inform any stubborn devices.

