UniFi OS Server
| Description / name | Input element |
|---|---|
| Container Registry | |
| Container Configuration Root Path | |
| UniFi OS Server /compat/linux/data Path |
Highly experimental: Ubiquiti UniFi OS Server on FreeBSD — runs the full UniFi management stack (unifi-core, UniFi Network) using FreeBSD jails and linuxulator.
Warning
Highly experimental. Ubiquiti does not ship UniFi OS Server for FreeBSD. This image cherry-picks the Linux binaries out of the official installer, runs them under linuxulator with stubs standing in for systemd, D-Bus, hardware identity and the package manager, and overlays a newer standalone Network release with UOS-only classes grafted from the bundle. It boots, restores Network backups and adopts devices, but a UOS or Network update can break any of that, and some console features (app installs, UOS backups, the unifi-core event stream to Network) are stubbed or known broken. Keep a working controller and a current backup; do not make this your only one.
| Registry | ghcr.io/daemonless/unifi-os-server |
| Daemonless | daemonless/unifi-os-server |
| Source | ui.com/consoles/unifi-os-server |
| Website | ui.com |
Version Tags
| Tag | Description | Best For |
|---|---|---|
latest |
Upstream Binary. Built from official release. | Most users — recommended. |
Linux binary compatibility must be loaded on the host. unifi-core, uos-agent and uid-agent are Linux ELF binaries run through linuxulator, and a jail cannot load kernel modules itself:
Before deploying, ensure your host environment is ready. See the Quick Start Guide for host setup instructions, including the security model for host vs. container privileges.
Deployment
Save as compose.yaml, then run podman-compose up -d.
Save the files above, then run appjail-director up.
Experimental
Bastille's OCI support is experimental. It requires buildah and shares the host network stack (inherit). Mount volumes with --volume HOST JAIL; without it, image-declared volumes are stored under ${bastille_volumesdir}/${jail}.
Save as bastille-compose.yml, then run bastille up.
Setup Instructions
Networking. The compose file in this repo runs with network_mode: host so UniFi's L2 device discovery works; add that line if your snippet lacks it. The server listens on 443 (web UI), 8080 (device inform), 8443 (Network HTTPS) and 3478/udp (STUN). On a bridge network instead, map those ports (-p 443:443 -p 8080:8080 -p 8443:8443 -p 3478:3478/udp); discovery will not work, so point devices at the controller yourself with set-inform http://<host-ip>:8080/inform or DHCP option 43.
First start. Open https://<host-ip>/ and complete the setup wizard. Its "restore from backup" step only lists cloud backups; to restore a Network .unf file, finish setup first, then use Settings → Backups → Restore in the console. The bundled Network application is the current standalone release, so backups from an up-to-date controller restore.
Moving devices from another controller. Adopted devices keep working and follow their inform URL. Move one with set-inform http://<host-ip>:8080/inform over SSH (the device SSH credentials are in the old controller's Device SSH Authentication settings), or move all of them by setting the old controller's Inform Host override to the new address. Shut the old controller down once everything is online.
Double /data mount. The Linux services open SQLite databases under the Linux compat root, so the same data directory must be mounted at both /data and /compat/linux/data.
Interactive Configuration
Parameters
Volumes
| Path | Description |
|---|---|
/data |
Persistent data (database, config, certs) |
/compat/linux/data |
Implementation Details
- Architectures: amd64
- User:
bsd(UID/GID set via PUID/PGID). Defaults to1000:1000. - Base: Built on
ghcr.io/daemonless/base(FreeBSD 15.1). - mlock: Requires
--annotation 'org.freebsd.jail.allow.mlock=true'(ocijail 0.5.0+) - sysvipc: Requires
--annotation 'org.freebsd.jail.allow.sysvipc=true'(ocijail 0.5.0+)
Need help? Join our Discord community.