Hướng dẫn cài UniFi Controller trên VPS chi tiết
Triển khai UniFi Network Application trên VPS hiệu quả. Hướng dẫn cấu hình Docker với MongoDB, thiết lập Layer 3 adoption qua lệnh set-inform và các port cần mở trên firewall.
Vai trò thực tế của UniFi controller trên VPS
UniFi controller trên VPS là một máy chủ quản lý duy nhất, vẫn có thể truy cập được ngay cả khi các site mà nó quản lý bị sập. Phần mềm này là UniFi Network Application của Ubiquiti: một chương trình Java chạy trên nền tảng cơ sở dữ liệu MongoDB. Nó thực hiện cấu hình các access point và switch, lưu trữ số liệu thống kê và cung cấp giao diện quản trị. Nó không trực tiếp truyền tải lưu lượng của client.
Điểm cuối cùng này quyết định vị trí đặt controller. Nếu đặt controller trên một máy bên trong văn phòng mà nó quản lý, bạn sẽ mất cả mạng lẫn công cụ để kiểm tra mạng đó cùng một lúc. Nếu đặt nó trên một VPS có địa chỉ public ổn định, nó sẽ tiếp tục chạy, tiếp tục thu thập dữ liệu và có thể nhận quản lý (adopt) thiết bị tại nhiều site từ một nơi duy nhất. Nó cần thời gian hoạt động liên tục (uptime), không cần hiệu năng phần cứng cao.
Khi controller ngoại tuyến, các access point và switch đã được adopt vẫn tiếp tục chuyển tiếp lưu lượng với cấu hình đã được đẩy xuống trước đó. Bạn sẽ mất bảng điều khiển (dashboard) và số liệu thống kê, cùng với bất kỳ tính năng nào yêu cầu controller phải trực tuyến: ví dụ như trang đăng nhập guest portal, hoặc RADIUS (remote authentication dial-in user service) nếu controller đóng vai trò là server RADIUS của bạn. Các client vẫn duy trì kết nối bình thường.
UniFi controller cần bao nhiêu RAM?
2 GB là mức tối thiểu và 4 GB là mức nên chọn. Có hai thành phần tiêu thụ bộ nhớ chính trong một hệ thống: Java và MongoDB, chúng tự phân bổ tài nguyên độc lập với nhau.
Java heap bị giới hạn bởi MEM_LIMIT, giá trị này được image container đặt mặc định là 1024 MB. MongoDB chiếm phần còn lại. Storage engine WiredTiger của nó tự đặt kích thước cache bằng một nửa lượng RAM dư ra sau khi trừ đi 1 GB, hoặc 256 MB, tùy theo giá trị nào lớn hơn. Trên một VPS 2 GB, con số này xấp xỉ 512 MB cache cộng với 1 GB heap, cộng thêm bộ nhớ non-heap của JVM và hệ điều hành. Nó vẫn chạy được cho đến khi gặp ngày cao điểm, lúc đó kernel out-of-memory killer sẽ kết thúc một trong hai tiến trình. Sau bất kỳ lần khởi động lại không rõ nguyên nhân nào, hãy chạy dmesg -T | grep -i 'killed process' để kiểm tra xem đó có phải là nguyên nhân hay không. Hãy thêm swap file nếu bạn chỉ có 2 GB RAM.
CPU và ổ cứng không đòi hỏi quá cao. Một hoặc hai vCPU có thể xử lý vài chục thiết bị. Hãy bắt đầu với 20 GB dung lượng ổ cứng và theo dõi nó, vì database sẽ phình to theo số lượng client bạn thấy và thời gian bạn lưu trữ thống kê. Một controller đơn lẻ sẽ để trống phần lớn tài nguyên trên một máy chủ 4 GB, vì vậy nếu bạn định chạy thêm dịch vụ khác, hãy tính toán tài nguyên cho dịch vụ đó trước, vì PhotoPrism và Immich có yêu cầu RAM tối thiểu rất khác nhau và cả hai đều đòi hỏi nhiều hơn controller.
Có một tính năng CPU cần lưu ý, và rất dễ bỏ qua trên các gói VPS giá rẻ:
grep -m1 -o avx /proc/cpuinfoMongoDB 5.0 trở lên yêu cầu AVX (advanced vector extensions) trên phần cứng x86_64. Nếu lệnh đó không trả về kết quả gì, mongod sẽ chết ngay khi khởi động và container sẽ khởi động lại liên tục, vì binary cố thực thi một tập lệnh mà CPU không hỗ trợ. Các dòng Intel Celeron và Pentium cũ thường là nguyên nhân, hoặc các hypervisor ẩn flag CPU khỏi guest. MongoDB 4.4 là bản release mới nhất chạy được mà không cần AVX, image cũng hỗ trợ các bản cũ hơn đến 3.6, nhưng 4.4 đã đạt end of life vào tháng 2 năm 2024. MongoDB có phát hành các bản build 4.4 cho bản vá tháng 12 năm 2025 đối với CVE-2025-14847, nhưng không có gì đảm bảo cho các lỗ hổng tiếp theo, và các bản release cũ hơn thì càng lạc hậu hơn nữa. Chuyển sang một host có CPU mới hơn là giải pháp tốt nhất. Trên VPS ARM, vấn đề này không tồn tại vì AVX là tập lệnh của x86, và cả hai image đều có bản build arm64. Nếu bạn đang phân vân giữa hai loại, sự khác biệt giữa các gói VPS ARM và x86 còn nhiều hơn cả vấn đề giá cả.
Cài đặt UniFi Network Application bằng Docker Compose
Docker là phương án ít gây bất ngờ nhất, vì nó cho phép bạn ghim (pin) phiên bản MongoDB mà ứng dụng hỗ trợ thay vì dùng phiên bản mà bản phân phối của bạn cung cấp. Nếu Docker chưa có trên máy, hãy cài đặt Docker trên VPS trước.
mkdir -p ~/unifi/config ~/unifi/db
cd ~/unifiMongoDB cần một người dùng trước khi ứng dụng có thể đăng nhập. Image MongoDB chính thức sẽ chạy bất kỳ script nào nó tìm thấy trong /docker-entrypoint-initdb.d ở lần khởi động đầu tiên. Hãy lưu nội dung này thành ~/unifi/init-mongo.sh:
#!/bin/bash
if which mongosh > /dev/null 2>&1; then
mongo_init_bin='mongosh'
else
mongo_init_bin='mongo'
fi
"${mongo_init_bin}" <<EOF
use ${MONGO_AUTHSOURCE}
db.auth("${MONGO_INITDB_ROOT_USERNAME}", "${MONGO_INITDB_ROOT_PASSWORD}")
db.createUser({
user: "${MONGO_USER}",
pwd: "${MONGO_PASS}",
roles: [
"clusterMonitor",
{ db: "${MONGO_DBNAME}", role: "dbOwner" },
{ db: "${MONGO_DBNAME}_stat", role: "dbOwner" },
{ db: "${MONGO_DBNAME}_audit", role: "dbOwner" },
{ db: "${MONGO_DBNAME}_restore", role: "dbOwner" }
]
})
EOFScript đó chỉ chạy khi thư mục cơ sở dữ liệu trống. Nếu bạn khởi động stack với mật khẩu sai, người dùng sẽ được tạo với mật khẩu sai đó. Việc chỉnh sửa file compose sau đó sẽ không có tác dụng vì script không bao giờ chạy lại. Triệu chứng là container ứng dụng sẽ báo lỗi xác thực MongoDB trong log, còn giao diện web thì không bao giờ xuất hiện. Với một bản cài mới, cách sửa là dừng stack, xóa ~/unifi/db và khởi động lại.
Sau đó, hãy viết file ~/unifi/compose.yaml:
services:
unifi-db:
image: docker.io/mongo:8.0
container_name: unifi-db
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=change-this-root-password
- MONGO_USER=unifi
- MONGO_PASS=change-this-unifi-password
- MONGO_DBNAME=unifi
- MONGO_AUTHSOURCE=admin
volumes:
- ./db:/data/db
- ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh:ro
restart: unless-stopped
unifi-network-application:
image: lscr.io/linuxserver/unifi-network-application:10.5.67-ls141
container_name: unifi-network-application
depends_on:
- unifi-db
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- MONGO_USER=unifi
- MONGO_PASS=change-this-unifi-password
- MONGO_HOST=unifi-db
- MONGO_PORT=27017
- MONGO_DBNAME=unifi
- MONGO_AUTHSOURCE=admin
- MEM_LIMIT=1024
- MEM_STARTUP=1024
volumes:
- ./config:/config
ports:
- "8080:8080"
- "3478:3478/udp"
- "127.0.0.1:8443:8443"
restart: unless-stoppedCả hai tag của image đều được ghim có chủ đích. 10.5.67-ls141 là bản phát hành ứng dụng hiện tại vào tháng 8 năm 2026, vì vậy hãy kiểm tra danh sách phát hành của image và ghim phiên bản mới nhất tại thời điểm bạn cài đặt. Tag của cơ sở dữ liệu quan trọng hơn. MongoDB không tự nâng cấp file dữ liệu giữa các phiên bản chính (major version), vì vậy mongo:latest một ngày nào đó sẽ kéo về một phiên bản chính mới, từ chối mở các file hiện có và khởi động lại liên tục. Hãy ghim phiên bản chính và chủ động nâng cấp khi cần. UniFi Network 8.1 trở lên hỗ trợ MongoDB 3.6 đến 7.0, và bản 9.0 đã thêm hỗ trợ cho MongoDB 8.0.
PUID và PGID phải khớp với một người dùng thực trên host, nếu không các file trong ./config sẽ thuộc sở hữu của một định danh không có quyền ghi. Chạy id để lấy thông tin của bạn. cách PUID và PGID hoạt động trong container image giải thích rõ về các lỗi do không khớp quyền.
Khởi động stack và theo dõi:
docker compose up -d
docker compose ps
docker compose logs -f unifi-network-applicationdocker compose ps sẽ hiển thị cả hai container ở trạng thái running. Một unifi-db bị kẹt ở trạng thái restarting thường là do vấn đề AVX đã nêu ở trên hoặc do vấn đề quyền truy cập trên ./db. Sau khi log ổn định, hãy kiểm tra hai cổng đang nghe:
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1:8443/
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/informBất kỳ mã trạng thái HTTP nào cũng có nghĩa là listener đã bind và đang phản hồi. Connection refused có nghĩa là ứng dụng vẫn đang khởi động (thường mất một hoặc hai phút trên VPS nhỏ trong lần chạy đầu tiên), hoặc ứng dụng chưa bao giờ khởi động được.
Truy cập giao diện quản trị mà không cần public ra ngoài
Cổng 8443 được publish trên 127.0.0.1 trong file cấu hình ở trên, vì vậy trên Docker Engine 28.0.0 trở lên, không có gì bên ngoài VPS có thể truy cập vào giao diện quản trị. Ở các bản release cũ hơn, các host khác trên cùng L2 segment, ví dụ như các máy trên cùng một network switch, có thể truy cập được các cổng publish ra localhost, nên hãy chạy docker version và nâng cấp trước nếu server báo phiên bản cũ hơn. Forward cổng qua SSH để chạy trình cài đặt:
ssh -L 8443:127.0.0.1:8443 you@vps.example.comGiữ nguyên session đó và truy cập vào https://127.0.0.1:8443. Chứng chỉ là self-signed nên trình duyệt sẽ cảnh báo một lần. Hãy tạo tài khoản quản trị viên, đặt tên cho site và tạm thời bỏ qua bước nhận thiết bị (device adoption).
SSH tunnel là giải pháp ổn cho một quản trị viên. Nếu làm việc theo nhóm, hãy cấp cho VPS một địa chỉ private và bind giao diện vào địa chỉ đó thay vì localhost. một VPN WireGuard trên VPS của bạn và một Tailscale subnet router đều cung cấp một địa chỉ mà chỉ những người trong nhóm của bạn mới có thể định tuyến tới. Thay đổi cổng publish thành 10.8.0.1:8443:8443 cho WireGuard, hoặc thành địa chỉ mà Tailscale cấp. Một lưu ý: Docker không thể publish trên một địa chỉ chưa tồn tại, vì vậy tunnel interface phải được khởi tạo trước khi container chạy, nếu không container sẽ fail với lỗi bind.
Tại sao thiết bị UniFi từ xa không thể adopt
Khi mới xuất xưởng, thiết bị UniFi tìm controller bằng cách broadcast trên mạng nội bộ qua cổng UDP 10001. Broadcast không vượt ra khỏi LAN, nên thiết bị ở một văn phòng tại thành phố khác sẽ không bao giờ tìm thấy controller trên VPS. Đây là quá trình Layer 3 adoption, nơi mà hầu hết mọi người đều gặp khó khăn. Thiết bị vẫn ổn và controller vẫn ổn. Chỉ là chưa có gì chỉ cho thiết bị biết nơi cần tìm.
Trước tiên, hãy cấu hình địa chỉ mà controller sẽ cung cấp. Trong phần Settings của controller, tại mục System, có thiết lập inform host với tùy chọn override. Hãy đặt nó thành hostname công khai hoặc IP của VPS. Nếu không có nó, controller sẽ quảng bá địa chỉ mà nó thấy trên giao diện của chính nó, vốn là một địa chỉ riêng như 172.18.0.3 nếu nằm trong Docker bridge network. Thiết bị nhận được địa chỉ đó, không thể định tuyến đến nó và quay lại trạng thái tìm kiếm.
Sau đó, hãy trỏ thiết bị về địa chỉ đó. SSH vào thiết bị trên LAN từ xa. Thiết bị mặc định xuất xưởng chấp nhận username ubnt với mật khẩu ubnt:
ssh ubnt@192.168.1.20
set-inform http://vps.example.com:8080/informFirmware thiết bị mới hơn sẽ đưa bạn vào một menu thay vì shell. Hãy chạy lệnh tương tự như một dòng lệnh đơn lẻ:
ssh ubnt@192.168.1.20 mca-cli-op set-inform http://vps.example.com:8080/informThiết bị giờ đây sẽ xuất hiện trong controller ở trạng thái sẵn sàng để adopt. Nhấp vào Adopt, trạng thái sẽ chuyển thành Adopting. Đây là phần khiến mọi người ngạc nhiên: bạn thường phải chạy set-inform lần thứ hai. Thiết bị khởi động lại vào quá trình provisioning và quay lại inform URL đã lưu trong cấu hình của chính nó, vốn là thứ mà controller chưa kịp thay thế xong. Chạy lại lệnh khi trạng thái đang là Adopting sẽ hoàn tất quá trình bàn giao. Gõ info trên thiết bị để xem inform URL và trạng thái hiện tại của nó.
Nếu thiết bị đã từng được adopt bởi một controller khác trước đó, chỉ dùng set-inform sẽ không thành công vì nó vẫn giữ thông tin xác thực của controller cũ. Hãy reset thiết bị về mặc định xuất xưởng trước, bằng nút reset hoặc bằng lệnh set-default qua SSH sử dụng thông tin xác thực cũ.
Với số lượng thiết bị lớn, hãy sử dụng DHCP thay thế. DHCP (dynamic host configuration protocol) option 43 mang một giá trị dành riêng cho nhà cung cấp, và các thiết bị UniFi đọc inform URL từ suboption 2. Hãy tạo chuỗi hex trên bất kỳ máy Linux nào:
URL="http://vps.example.com:8080/inform"
HEX=$(printf '%s' "$URL" | od -An -tx1 | tr -d ' \n')
printf '02%02x%s\n' "${#URL}" "$HEX"Với http://192.168.3.10:8080/inform, một chuỗi 31 byte, nó sẽ in ra 021f687474703a2f2f3139322e3136382e332e31303a383038302f696e666f726d. Dán kết quả vào trường DHCP option 43 trên router của bạn dưới dạng giá trị hex. Mọi thiết bị khởi động trên mạng đó sau đó sẽ nhận được địa chỉ controller từ lease của nó mà không cần SSH. Các hướng dẫn cũ hơn hiển thị suboption 1 thay thế, 0104 theo sau là bốn byte của địa chỉ IPv4 dưới dạng hex, và các thiết bị vẫn chấp nhận định dạng đó.
Có một cách thứ ba nếu bạn chạy DNS tại site đó. Thiết bị UniFi cố gắng phân giải hostname unifi khi khởi động, vì vậy một bản ghi A cho unifi trỏ đến địa chỉ VPS của bạn sẽ giúp adopt thiết bị mà không cần thao tác trên từng thiết bị. Cách này chỉ hiệu quả khi bạn kiểm soát được trình phân giải (resolver) mà các thiết bị thực sự sử dụng.
Các cổng UniFi cần mở và các cổng cần giữ riêng tư
Hai cổng cần phải truy cập được từ một site từ xa để thực hiện adoption và quản lý hàng ngày.
- TCP 8080 là kênh inform, mọi thiết bị đã được adopt đều kết nối vào đây. Payload bên trong được mã hóa AES bằng một key mà controller đã cấp cho thiết bị trong quá trình adoption, đó là lý do tại sao HTTP thường là thiết lập mặc định ở đây.
- UDP 3478 là STUN (session traversal utilities for NAT), được các thiết bị sử dụng để duy trì đường truyền quay lại controller.
Một số tính năng cần nhiều hơn thế. Tài liệu tham khảo về cổng của Ubiquiti bổ sung TCP 5671 cho việc ghi log Traffic Flow từ các gateway UXG được adopt trên mạng L2 hoặc L3. Vì vậy, nếu một site có UXG báo cáo về controller này và bạn muốn lấy các log đó, hãy mở cổng 5671 cho site đó.
Mọi cổng khác phải đóng trên VPS.
- TCP 8443 là giao diện quản trị. Đây là cổng tuyệt đối không được để public. Nó chứa cấu hình cho mọi site mà controller quản lý, chỉ được bảo vệ bởi một mật khẩu.
- UDP 10001 và UDP 1900 là các cổng broadcast discovery. Broadcast không truyền qua internet, nên việc mở chúng không có tác dụng gì.
- TCP 8880 và TCP 8843 là các cổng chuyển hướng guest portal. Chỉ mở chúng nếu bạn đang chạy guest portal.
- TCP 6789 là cổng kiểm tra tốc độ trên thiết bị di động và UDP 5514 là remote syslog. Hãy thêm chúng khi bạn sử dụng.
- TCP 27117 là MongoDB. Trong file compose ở trên, database không publish bất kỳ cổng nào, nên nó chỉ tồn tại trên mạng Docker nội bộ. Hãy giữ nguyên như vậy.
Nếu các site của bạn có địa chỉ public tĩnh, chỉ cho phép các địa chỉ đó:
sudo ufw allow OpenSSH
sudo ufw allow proto tcp from 203.0.113.4 to any port 8080
sudo ufw allow proto udp from 203.0.113.4 to any port 3478
sudo ufw enable
sudo ufw status verbosecác kiến thức cơ bản về ufw cho firewall VPS bao gồm thiết lập mặc định từ chối (deny) mà các rule đó giả định.
Có một cái bẫy khiến mọi người thường xuyên mắc phải. Các cổng được publish bởi Docker sẽ bỏ qua ufw. Việc publish một cổng sẽ ghi các rule NAT và forwarding trực tiếp vào iptables, và lưu lượng đó được lọc trong chain riêng của Docker, không phải trong chain INPUT mà ufw quản lý. Vì vậy, ufw deny 8443 trông có vẻ đúng trong ufw status trong khi cổng vẫn mở ra toàn thế giới. Hãy kiểm tra từ một máy khác, đừng bao giờ kiểm tra từ chính VPS đó:
nc -vz vps.example.com 8443Kết quả bạn cần là từ chối hoặc timeout. Nếu nó kết nối được, cổng đó đang public bất kể ufw nói gì. Cách sửa lỗi đáng tin cậy là cách đã có trong file compose: publish cổng trên 127.0.0.1 hoặc trên một địa chỉ tunnel, để Docker không bao giờ bind nó vào giao diện public. Một rule trong chain DOCKER-USER cũng có hiệu quả, nhưng việc bind địa chỉ đơn giản hơn và không thể bị vô hiệu hóa do sai sót về thứ tự rule.
Còn các trình cài đặt của riêng Ubiquiti thì sao?
Ubiquiti phát hành một gói Debian cho Network Application, và tính đến tháng 10 năm 2026, trung tâm trợ giúp của họ gắn nhãn phương thức đó là legacy và gọi UniFi OS Server là tiêu chuẩn mới cho việc tự host. Gói này vẫn hoạt động, nhưng trên các bản Ubuntu hiện tại, nó gây ra vấn đề về MongoDB mà bản phân phối không còn hỗ trợ: Ubuntu 22.04 và 24.04 không cung cấp gói MongoDB server, vì vậy bạn phải tự thêm repository của MongoDB và khớp các phiên bản theo cách thủ công. Container ở trên thực hiện việc khớp phiên bản đó trong một tag cố định, đó là lý do tại sao nó là lựa chọn được ưu tiên ở đây.
Sản phẩm tự host mới hơn của Ubiquiti là UniFi OS Server, chạy các ứng dụng UniFi trong các container Podman và cung cấp cho bạn UniFi OS giống như trên các thiết bị console phần cứng của họ. Tính đến tháng 10 năm 2026, Ubiquiti yêu cầu CPU x86-64, Ubuntu 24.04 trở lên hoặc Debian 13 trở lên, Podman 4.9.3 trở lên với slirp4netns 1.2 trở lên, ít nhất 2 GB RAM và 10 GB dung lượng lưu trữ trống. Liên kết trình cài đặt trên trang Releases hoặc Download của Ubiquiti là dành riêng cho từng phiên bản: hãy chuột phải vào tệp tải xuống, sao chép địa chỉ liên kết và tải về bằng curl -O hoặc wget. Mỗi bản phát hành có một URL riêng, vì vậy một hướng dẫn có thể ghim một phiên bản cụ thể nhưng không thể cung cấp cho bạn một liên kết luôn trỏ đến phiên bản mới nhất. Trình cài đặt sẽ thiết lập một service systemd có tên là uosserver, bạn dùng systemctl để dừng và khởi động nó. Hãy chọn cách này nếu bạn muốn sử dụng gói cài đặt chính chủ từ nhà sản xuất. Hãy chọn stack container nếu bạn muốn tự mình ghim phiên bản và giữ cho máy chủ trống để thực hiện các công việc khác.
Vị trí lưu backup UniFi và cách lấy chúng ra khỏi máy chủ
Controller tự ghi các bản backup theo lịch trình bạn thiết lập trong phần Settings, mục backup, cùng với số lượng bản lưu giữ. Các file này nằm tại /config/data/backup/autobackup bên trong container, tương ứng với ~/unifi/config/data/backup/autobackup trên host, có tên dạng autobackup_10.5.67_20260813_1200_1755086400004.unf.
Kiểm tra xem chúng đã xuất hiện chưa:
ls -l ~/unifi/config/data/backup/autobackupThư mục trống sau một ngày thiết lập lịch trình là lỗi thường gặp trên các bản cài đặt container mới. Ứng dụng yêu cầu thư mục autobackup phải tồn tại nhưng lại không tự tạo nó, dẫn đến việc tác vụ theo lịch trình không ghi được gì mà không báo lỗi. Hãy tự tạo thư mục này với cùng user đang chạy container, sau đó đợi lần chạy tiếp theo:
mkdir -p ~/unifi/config/data/backup/autobackup
docker compose restart unifi-network-applicationFile .unf chứa cấu hình site và các tài khoản quản trị, vì vậy hãy coi nó như một key bảo mật. Hãy tải các bản sao về máy bạn quản lý và giữ chúng ở nơi an toàn:
rsync -av you@vps.example.com:~/unifi/config/data/backup/autobackup/ ~/unifi-backups/Việc khôi phục chỉ gồm một bước. Trang đầu tiên của trình cài đặt trên một bản cài mới sẽ cho phép bạn khôi phục từ file backup, và một controller đang chạy cũng có thể nhận file từ chính trang cài đặt đó. Hãy khôi phục vào cùng phiên bản hoặc phiên bản mới hơn. Bản backup được tạo bởi ứng dụng phiên bản mới hơn phiên bản bạn đang khôi phục sẽ bị từ chối, đó là lý do bạn cần ghi lại số phiên bản cùng với file backup.
Những lỗi có thể xảy ra khi nâng cấp controller
Hãy thực hiện backup thủ công và tải về trước mỗi lần nâng cấp. Sau đó:
docker compose pull
docker compose up -d
docker compose logs -f unifi-network-applicationDatabase là thành phần dễ gặp sự cố nhất. Việc thay đổi tag mongo sang một phiên bản major mới trong cùng một lần chỉnh sửa với ứng dụng là cách nhanh nhất khiến controller không thể khởi động, vì MongoDB sẽ không mở được các file dữ liệu từ một phiên bản major khác nếu không thực hiện nâng cấp theo từng giai đoạn. Hãy nâng cấp ứng dụng riêng biệt. Di chuyển MongoDB tách biệt, từng phiên bản major một, với bản backup mới nhất trong tay.
Bộ nhớ là vấn đề tiếp theo. Một bản release lớn hơn đòi hỏi heap lớn hơn. Nếu ứng dụng khởi động, chạy được vài phút rồi chết, hãy tăng MEM_LIMIT và MEM_STARTUP lên 1536 hoặc 2048 rồi khởi động lại. Lệnh dmesg -T | grep -i 'killed process' trên host sẽ xác nhận liệu kernel có phải là tác nhân kết thúc tiến trình đó hay không.
Firmware thiết bị là rủi ro mà mọi người thường quên. Sau khi controller tự nâng cấp, nó sẽ đề xuất nâng cấp firmware cho các thiết bị đã được adopt. Đừng chấp nhận các nâng cấp này trong cùng một phiên làm việc. Nếu việc nâng cấp thiết bị và nâng cấp controller diễn ra chồng chéo và kết nối giữa chúng bị ngắt, thiết bị có thể rơi vào trạng thái cấu hình dở dang, và bạn sẽ phải quay lại dùng set-inform qua SSH trên phần cứng ở một tòa nhà khác.
Khoảng thời gian nâng cấp thực tế nhẹ nhàng hơn bạn nghĩ. Các thiết bị vẫn tiếp tục chuyển tiếp lưu lượng trong khi controller khởi động lại, nên người dùng sẽ không thấy gián đoạn. Thứ bị dừng lại là guest portal và RADIUS nếu controller đảm nhiệm vai trò đó, vì vậy hãy chọn thời điểm không ai sử dụng các dịch vụ này. Một controller chết lặng lẽ vào lúc 3 giờ sáng là điều cần biết, vì vậy hãy trỏ một Uptime Kuma status monitor vào cổng 8080 để nó thông báo cho bạn.
Giải pháp thay thế trung thực: Console được host bởi Ubiquiti
Ubiquiti cung cấp dịch vụ quản lý tương tự dưới dạng một gói dịch vụ. Tính đến tháng 10 năm 2026, cửa hàng tại Mỹ của Ubiquiti bán dịch vụ này dưới tên gọi Official UniFi Hosting, với giá từ 29 USD mỗi tháng, hỗ trợ quản lý tối đa 1.000 thiết bị UniFi Network trên máy chủ do Ubiquiti vận hành. Ứng dụng tự host mà bạn vừa cài đặt là miễn phí và không yêu cầu đăng ký thuê bao.
Hãy chọn console được host nếu bạn chỉ quản lý một site và muốn trả phí thay vì phải tự bảo trì. Hãy chọn VPS nếu bạn quản lý nhiều site, hoặc nếu bạn muốn controller nằm trong mạng do bạn kiểm soát và chạy chung trên một máy chủ với các dịch vụ khác. Sự khác biệt về chi phí ở quy mô nhỏ là đáng kể, nhưng đó không phải là yếu tố duy nhất cần cân nhắc: console được host đồng nghĩa với việc bạn phụ thuộc vào thời gian uptime của người khác, còn với VPS, bạn tự chịu trách nhiệm, bao gồm cả những đêm ổ cứng bị đầy. Nếu máy chủ đó vẫn cần phải hoạt động hiệu quả, những gì bạn có thể chạy trên VPS là danh sách bạn nên đọc tiếp theo.
FAQ
Tại sao thiết bị UniFi của tôi không thể adopt vào controller trên VPS?
Các thiết bị tìm kiếm controller bằng cách broadcast trên cổng UDP 10001, và broadcast không bao giờ vượt ra khỏi mạng nội bộ, vì vậy thiết bị ở site từ xa không thể tìm thấy controller trên internet công cộng. Hãy thiết lập inform host override trong cài đặt hệ thống của controller thành hostname VPS của bạn, sau đó trỏ thiết bị vào đó bằng ssh ubnt@<device-ip> theo sau là set-inform http://vps.example.com:8080/inform. Nếu thiết bị bị kẹt ở trạng thái Adopting, hãy chạy lại set-inform khi nó đang ở trạng thái đó. Nếu thiết bị đã từng được adopt bởi một controller khác, hãy reset nó về mặc định nhà sản xuất trước, vì nó vẫn đang lưu thông tin xác thực của controller cũ.
UniFi controller tự host cần bao nhiêu RAM?
2 GB là mức tối thiểu để hoạt động và 4 GB là mức thoải mái. Ứng dụng này bao gồm Java và MongoDB, cả hai đều tự phân bổ bộ nhớ riêng: image container giới hạn Java heap ở mức 1024 MB theo mặc định, trong khi WiredTiger cache của MongoDB chiếm một nửa lượng RAM trên 1 GB. Trên x86_64, hãy xác nhận CPU có hỗ trợ AVX bằng grep -m1 -o avx /proc/cpuinfo, vì MongoDB 5.0 trở lên sẽ không khởi động được nếu thiếu nó và container cơ sở dữ liệu sẽ khởi động lại liên tục.
Tôi có nên mở cổng 8443 ra internet không?
Không. Cổng 8443 là giao diện quản trị, chứa cấu hình cho mọi site mà controller quản lý. Hãy publish nó trên 127.0.0.1 với Docker Engine 28.0.0 trở lên và truy cập bằng ssh -L 8443:127.0.0.1:8443 you@vps.example.com, hoặc bind nó vào địa chỉ WireGuard hoặc Tailscale. Để phục vụ việc adopt và quản lý, các site của bạn cần kết nối được tới TCP 8080 và UDP 3478, cộng thêm TCP 5671 nếu UXG gateway gửi Traffic Flow log về controller. Bạn có thể giới hạn các cổng này theo địa chỉ IP công cộng của các site nếu chúng là IP tĩnh. Hãy nhớ rằng cổng đã publish qua Docker không bị lọc bởi ufw, vì vậy hãy kiểm tra từ một máy bên ngoài thay vì tin tưởng vào ufw status.
Mạng của tôi có ngừng hoạt động nếu VPS controller bị sập không?
Không. Các access point và switch đã được adopt vẫn tiếp tục chuyển tiếp lưu lượng dựa trên cấu hình mà controller đã đẩy xuống, vì vậy client vẫn kết nối được và Wi-Fi vẫn hoạt động bình thường. Thứ bị gián đoạn là khả năng quản lý. Bạn sẽ mất dashboard và khả năng thu thập thống kê, cùng với bất kỳ tính năng trực tiếp nào mà controller cung cấp, ví dụ như xác thực guest portal hoặc RADIUS nếu controller đóng vai trò là RADIUS server.
UniFi controller lưu các bản backup tự động ở đâu?
Trong image container được sử dụng ở đây, chúng nằm trong /config/data/backup/autobackup, đường dẫn này được map tới data path của bạn cộng với data/backup/autobackup trên host, dưới dạng các file .unf được đặt tên theo phiên bản và dấu thời gian. Trên một số bản cài đặt mới, thư mục autobackup không tồn tại, và lịch backup sẽ không ghi được gì mà không báo lỗi, vì vậy hãy kiểm tra thư mục đó một ngày sau khi bạn đặt lịch và tự tạo nó nếu nó trống. Hãy copy các file này ra khỏi VPS, vì một file .unf chứa toàn bộ cấu hình site và các tài khoản quản trị viên.