Self-hosting the UniFi Controller

July 19, 2025 · Vivaan M #Lab #Services #Guide #Networking

In order to fully utilise the UniFi APs full feature set, you’ll need to have a UniFi controller of some sort. This can be a UniFi Cloud Key, a UniFi Cloud Gateway, or… you can host one yourself. So obviously, I chose the third option.

There are two methods for installing the controller. One is on Docker, or you can use a Bare-Metal install. I’ll go through both, but I personally use the Docker setup.

Docker

Well, in order to do this, you obviously need to have Docker installed - if not, see here for how to do that.

Compose file

 1version: "3.9"
 2name: unifi
 3
 4services:
 5  unifi-db:
 6    container_name: unifi-db
 7    image: mongo:3.6
 8    environment:
 9      - TZ=Etc/UTC
10    volumes:
11      - /srv/unifi/db:/data/db
12      - /srv/unifi/init/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
13    networks:
14      - unifi
15    restart: unless-stopped
16    healthcheck:
17      test: ["CMD", "mongo", "--eval", "db.adminCommand('ping')"]
18      interval: 10s
19      timeout: 5s
20      retries: 5
21
22  unifi-network-application:
23    container_name: unifi-network-application
24    image: lscr.io/linuxserver/unifi-network-application:latest
25    depends_on:
26      unifi-db:
27        condition: service_healthy
28    environment:
29      - MONGO_DBNAME=unifi-db
30      - MONGO_HOST=unifi-db
31      - MONGO_PORT=27017
32      - MONGO_USER=unifi
33      - MONGO_PASS=pass
34      - PGID=1000
35      - PUID=1000
36      - TZ=Etc/UTC
37    ports:
38      - 3478:3478/udp
39      - 10001:10001/udp
40      - 8080:8080
41      - 8443:8443
42      - 8843:8843
43      - 6789:6789
44    volumes:
45      - /srv/unifi/network-application:/config
46    networks:
47      - unifi
48      - proxy
49    restart: unless-stopped
50
51networks:
52  unifi:
53    driver: bridge
54    ipam:
55      config:
56        - subnet: 172.28.0.0/16
57  proxy:
58    external: true

/srv/unifi/init/init-mongo.js

 1db.getSiblingDB("unifi-db").createUser({
 2  user: "unifi",
 3  pwd: "pass",
 4  roles: [{ role: "dbOwner", db: "unifi-db" }]
 5});
 6
 7db.getSiblingDB("unifi-db_stat").createUser({
 8  user: "unifi",
 9  pwd: "pass",
10  roles: [{ role: "dbOwner", db: "unifi-db_stat" }]
11});

You can change the password by changing pass to a value of your preference.

After this, run docker compose up -d in the directory you have placed the compose file in, and it should start running.

Now head to setup:

Bare-metal

This only works on Debian or Ubuntu machines, credit to https://community.ui.com/user/AmazedMender16/ed097858-e875-46ba-b9ea-7c65e2747440, for his script to do so.

Install pre-requisites

Ensure the ca-certificates package is installed.

1sudo apt-get update; sudo apt-get install ca-certificates curl -y

Download and execute script

1curl -sO https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && sudo bash unifi-latest.sh

Examples (if exposing directly)

1curl -sO https://get.glennr.nl/unifi/install/install_latest/unifi-latest.sh && sudo bash unifi-latest.sh --email hello@848226.xyz --skip --fqdn unifi.848226.xyz

Exposing

With NGINX Proxy Manager

You will need to create a new Proxy Host.

Details

image.png

SSL

image.png

Advanced

image.png

 1location / {
 2    # Proxy Unifi Controller UI traffic
 3    # The lack of '/' at the end is significant.
 4    proxy_pass https://YOUR_SERVER_IP:8443;
 5    proxy_ssl_verify off;
 6    proxy_ssl_session_reuse on;
 7    proxy_buffering off;
 8    proxy_set_header Upgrade $http_upgrade;
 9    proxy_set_header Connection "upgrade";
10    ## Specific to Unifi Controller
11    proxy_hide_header Authorization;
12    proxy_set_header Referer '';
13    proxy_set_header Origin '';
14}
15
16location /inform {
17    # Proxy Unifi Controller inform endpoint traffic
18    # The lack of '/' at the end is significant.
19    proxy_pass https://YOUR_SERVER_IP:8080;
20    proxy_ssl_verify off;
21    proxy_ssl_session_reuse on;
22    proxy_buffering off;
23    proxy_set_header Upgrade $http_upgrade;
24    proxy_set_header Connection "upgrade";
25    ## Specific to Unifi Controller
26    proxy_hide_header Authorization;
27    proxy_set_header Referer '';
28    proxy_set_header Origin '';
29}
30
31location /wss {
32    # Proxy Unifi Controller UI websocket traffic
33    # The lack of '/' at the end is significant.
34    proxy_pass https://YOUR_SERVER_IP:8443;
35    proxy_http_version 1.1;
36    proxy_set_header Upgrade $http_upgrade;
37    proxy_set_header Connection "upgrade";
38    ## Specific to Unifi Controller
39    proxy_set_header Origin '';
40    proxy_buffering off;
41    proxy_hide_header Authorization;
42    proxy_set_header Referer '';
43}

Directly exposing

Expose the following ports in your firewall (only port forward if you are running your UniFi controller off-site from your UniFi devices):

  • 3478
  • 10001
  • 8080
  • 8443
  • 8843
  • 6789

Setup

Now you must go through the setup process for the UniFi controller. In order to adopt new UniFi devices to your self-hosted controller, follow the following steps:

Connect

SSH to your UniFi Device, using it’s IP Address, which can be found in your router’s dashboard:

1ssh ubnt@YOUR_DEV_IP

with a default password of ubnt

Set the inform URL

Get your controller IP Address, or the hostname which you are exposing it on, and run the following command:

1set-inform http://YOUR_UNIFI_CONTROLLER/inform

Complete adoption

Head to your controller, login, click UniFi Devices in the sidebar, and you should see your device waiting for adoption.

Final Thoughts

I think self-hosting the UniFi controller is a great way to be able to use UniFi devices without having to purchase a dedicated controller, especially if you already have the infrastructure and knowledge in order to do so.