If you've got a Ubiquiti access point or switch sitting on your network, you've probably run into the same wall every homelab owner hits eventually: the free Cloud Key is $80+ and the mobile app only gets you so far before you want the full desktop controller. The good news is you don't need Ubiquiti's hardware to run Ubiquiti's software. The UniFi Network Application is just a Java app with a MongoDB database behind it, and it runs happily in a small Linux container.

This guide walks through building that container on Proxmox VE from scratch — no Docker, no pre-built appliance, just the same install process Ubiquiti documents for any Debian server, adapted for an LXC container. It takes about twenty minutes if you copy-paste carefully, longer if you're troubleshooting a MongoDB version mismatch (more on that below, because it will bite someone).

What You Will Learn

By the end of this tutorial you'll have a working UniFi Network Controller running inside its own LXC container, reachable from your browser, and adopting real Ubiquiti hardware. Specifically, you'll learn:

  • What the UniFi Network Application actually is and why self-hosting it beats the Cloud Key for most homelabs
  • How to size and create a Debian-based LXC container in Proxmox VE for this workload
  • The exact package chain — MongoDB, Java, then the UniFi package itself — and why the order matters
  • How to adopt existing access points and switches into your new controller
  • The specific hardware gotcha that stops this dead on older CPUs, and how to check for it before you waste an hour

What Is This Feature?

The UniFi Network Application (most people still call it "the UniFi Controller," which was its name before Ubiquiti rebranded) is the management software behind every Ubiquiti UniFi access point, switch, and gateway. It's where you set up Wi-Fi networks, VLANs, firewall rules, and see which devices are connected to what. Every UniFi device needs to talk to a controller somewhere — that's either Ubiquiti's cloud service, a physical Cloud Key appliance, or a copy of the same software running on your own server.

Under the hood it's a fairly ordinary stack: a Java application server, backed by a MongoDB database, serving a web UI over HTTPS on port 8443. There's nothing UniFi-specific about the underlying Linux setup — it's the same install whether you're on bare metal, a VM, or, as we're doing here, an LXC container.

An LXC container, if you haven't used one before, is a lightweight form of virtualization that shares the host's kernel instead of running a full separate operating system like a VM does. For an app like this — one process, one database, no exotic kernel modules — a container boots in seconds and uses a fraction of the RAM a VM would need for the same job.

Why Would You Use It?

Three real reasons people do this, and none of them are "because it's cool":

First, cost. A Cloud Key Gen2+ runs somewhere north of $100, and it's one more piece of hardware that can fail. If you're already running Proxmox, the controller is effectively free — it's a couple gigs of RAM you already have.

Second, control. Self-hosting means your device inform data, WiFi passwords, and network topology stay on your own storage instead of round-tripping through Ubiquiti's cloud (unless you choose to enable remote access, which is optional).

Third, and this is the one people don't expect: it survives hardware failure better. If your Cloud Key dies, you're waiting on a replacement and hoping you have a recent backup. If your LXC container has a problem, you restore last night's Proxmox backup and you're back online in minutes.

Honestly, if you only own one or two UniFi devices and never touch advanced settings, the mobile app alone might be enough and this is overkill. But if you're running VLANs, multiple APs, or you just like having the full dashboard, this is worth the twenty minutes.

Prerequisites

Before you start, make sure you have:

  • A Proxmox VE host on 8.x or 9.x (this guide was tested against 9.2)
  • At least 2GB of RAM and 8GB of disk space free for the new container
  • A Debian 12 (Bookworm) LXC template downloaded, or internet access to fetch one
  • Your Ubiquiti hardware (AP, switch, or gateway) already on the same network, powered on, and running current firmware
  • A CPU that supports AVX instructions — check this now, it's explained below, and it will save you a support forum rabbit hole later

On that last point: starting with MongoDB 5.0, Mongo requires a CPU with AVX (Advanced Vector Extensions) support. Most Intel CPUs from roughly the last decade have it, but a surprising number of older Xeons, budget NUCs, and some low-power Atom-based boxes people run Proxmox on do not. Run cat /proc/cpuinfo | grep avx on your Proxmox host before you begin. If nothing prints, MongoDB 7.0 will refuse to start no matter how correctly you follow the rest of this guide, and you'd need to fall back to an older Mongo release UniFi no longer officially supports. It's a five-second check that saves real frustration.

Step-by-Step Tutorial

1. Create the LXC container

In the Proxmox web UI, click Create CT in the top right. Give it a hostname like unifi, set a root password, and on the Template step pick debian-12-standard. We're deliberately using Debian 12 here rather than the newer Debian 13 template that ships with Proxmox VE 9 — MongoDB's official repository and compatibility testing for the 7.0 line are documented against Bookworm, and there's no upside to fighting an unsupported combination on day one.

On the Resources step, give it 2 CPU cores, 2048 MB of RAM, and 8GB of disk. UniFi's own footprint is small, but MongoDB and the JVM both want headroom — 1GB RAM works until your controller history grows, then things get sluggish. On the Network step, attach it to your usual bridge (vmbr0) with either a static IP or a DHCP reservation. You want this address to never change, since every adopted device will be configured to phone home to it.

Leave the container unprivileged — the default. Nothing about this workload needs privileged access to the host, and there's no reason to accept that extra risk for an app that's just Java and Mongo.

2. Update the container and install base packages

Start the container and open its console (or SSH in once networking is confirmed). Run:

apt update && apt full-upgrade -y
apt install -y curl gnupg apt-transport-https ca-certificates

This isn't just habit — the UniFi and MongoDB repositories we're about to add both rely on GPG-signed packages, and gnupg and ca-certificates need to already be present for those signature checks and HTTPS repo fetches to work.

3. Install MongoDB 7.0

Debian dropped MongoDB from its own repositories years ago over licensing, so it has to come from MongoDB's official repo directly:

curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
https://repo.mongodb.org/apt/debian bookworm/mongodb-org/7.0 main" | \
  tee /etc/apt/sources.list.d/mongodb-org-7.0.list

apt update
apt install -y mongodb-org
systemctl enable --now mongod

Check it actually started before moving on: systemctl status mongod should show active (running). If it doesn't, stop here — this is almost always the AVX issue mentioned in Prerequisites.

4. Install Java

The UniFi Network Application needs a Java 17 runtime. Bookworm ships it in the default repos, so this is the easy step:

apt install -y openjdk-17-jre-headless

5. Add the Ubiquiti repository and install UniFi

curl -fsSL https://dl.ui.com/unifi/unifi-repo.gpg \
  -o /etc/apt/trusted.gpg.d/unifi-repo.gpg

echo 'deb [arch=amd64,arm64,signed-by=/etc/apt/trusted.gpg.d/unifi-repo.gpg] \
https://www.ui.com/downloads/unifi/debian stable ubiquiti' | \
  tee /etc/apt/sources.list.d/100-ubnt-unifi.list

apt update
apt install -y unifi

Because Mongo and Java are already in place, this install should complete without pulling in anything unexpected. Once it finishes, confirm the service is running:

systemctl enable --now unifi
systemctl status unifi

Give it a minute on first boot — the JVM has to initialize the database schema the first time it starts, and the web UI won't respond until that finishes.

6. Open the web setup wizard

From a browser on the same network, go to https://<container-ip>:8443. You'll get a certificate warning — the controller uses a self-signed cert by default — which is expected and safe to accept on your own LAN. Walk through the setup wizard: name your site, create your local admin account, and skip the Ubiquiti cloud login step if you'd rather keep this fully local.

7. Adopt your devices

If your container is on the same Layer 2 network as your UniFi devices, they should show up under Devices as pending adoption within a minute or two — click Adopt next to each one. If they're on a routed or VLAN-separated network, broadcast discovery won't reach them, and you'll need to SSH into each device and manually point it at the controller:

set-inform http://<container-ip>:8080/inform

Commands Explained

CommandWhat it does
apt full-upgrade -yUpgrades all installed packages, including ones that need to remove or replace other packages to satisfy dependencies — safer than a plain upgrade right after a fresh template install.
gpg --dearmorConverts an ASCII-armored GPG key into the binary keyring format modern apt expects for the signed-by option, instead of the deprecated global apt-key method.
systemctl enable --now <service>Starts the service immediately and also configures it to start automatically on the next container boot — one command instead of two.
set-informA command run directly on a UniFi device's own shell (via SSH) that tells it the URL of the controller it should report to, used when automatic Layer 2 discovery can't reach the controller.

Common Errors

"Job for mongod.service failed" — check journalctl -u mongod -n 50. If you see anything mentioning Illegal instruction or the process dying instantly with no clear log line, it's the AVX problem. There's no config fix; MongoDB 5.0 and later simply won't run on a CPU without it.

The setup wizard never loads, connection just times out — almost always the container's firewall or the Proxmox host firewall blocking port 8443. Double check with ss -tlnp | grep 8443 from inside the container to confirm the JVM is actually listening before you go hunting through firewall rules.

apt install unifi fails with unmet dependencies — this means Mongo or Java wasn't installed first, or the Mongo repo line has a typo (check the codename matches your container's actual Debian release with cat /etc/os-release).

Devices show as "Pending" but never finish adopting — usually a one-way communication problem: the device can reach the controller on 8080, but the controller can't reach back to the device's management IP. Check that your container and your UniFi devices are genuinely on the same subnet, not separated by an unexpected VLAN tag on the bridge.

Troubleshooting

Start with the logs, not the web UI. journalctl -u unifi -f streams the controller's own log in real time and will usually name the actual failure — a Mongo connection refusal, a Java version mismatch, or a port conflict — long before the browser gives you anything useful.

If Mongo is running but UniFi still won't start, check that Java resolves to the right version: java -version should report 17. Multiple JRE installs from earlier troubleshooting attempts are a common source of confusion here.

If adoption is the sticking point rather than the install itself, confirm from inside the container that it can actually reach a device's IP with a plain ping. A routed network, an isolated VLAN, or a misconfigured Proxmox bridge will all produce the same symptom — devices visible on the network but never adopting — and this rules out half the possible causes in one command.

Best Practices

Back this container up like you would any other stateful service. A vzdump backup taken before you upgrade the UniFi package means a bad update is a five-minute restore instead of a rebuild from scratch.

Keep the controller version and your device firmware reasonably close together — jumping several major UniFi versions at once occasionally trips up devices running very old firmware. Update firmware first, then the controller, not the other way around.

Don't expose port 8443 directly to the internet. If you want remote access, put it behind a VPN (WireGuard is a common pairing on Proxmox homelabs) rather than port-forwarding straight to the container.

Give the container a fixed IP via DHCP reservation rather than a floating lease. Every adopted device stores the controller's address — if that address changes, you'll be re-pointing every AP and switch by hand.

Frequently Asked Questions

Do I need a UniFi gateway or router to use this?

No. The controller manages APs and switches independently of what's routing your network — a pfSense box, an ISP router, or a UniFi gateway all work the same way from the controller's perspective.

Can I run this in a full VM instead of an LXC container?

Yes, and it works identically. LXC just uses noticeably less RAM and boots faster for a workload this small, which is why it's the more common choice on Proxmox.

Is running UniFi in an LXC container officially supported by Ubiquiti?

Ubiquiti documents self-hosting on a standard Debian or Ubuntu server. An LXC container running Debian is functionally the same OS from the application's point of view, but the container packaging itself is a community pattern, not something Ubiquiti tests or supports directly.

Why Debian 12 instead of the newer Debian 13 template?

MongoDB's compatibility testing and official repository support for the 7.0 line are documented against Bookworm. Trixie support will likely follow, but there's no reason to be the one debugging that gap.

How much storage should I actually allocate?

8GB is enough to start. Controller history and Mongo's own overhead grow slowly, so check disk usage every few months rather than over-provisioning heavily up front.

Conclusion

Once it's running, this is one of those services you set up once and mostly forget about — it just sits there, tracks your network, and gets backed up along with everything else on your Proxmox host. The install chain looks longer written out than it actually is in practice: Mongo, Java, UniFi, in that order, and the AVX check up front so you're not debugging a CPU limitation an hour in. If you've been putting off ditching the mobile app for the real dashboard, this is a fairly quick weekend project.