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?
Hai GB là mức tối thiểu và 4 GB là con số bạn nên mua. Có hai thành phần tiêu thụ bộ nhớ trong một hệ thống, Java và MongoDB, và chúng tự cấp phát 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 trên 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 ổn 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 ổ cứng và theo dõi nó, vì cơ sở dữ liệu sẽ tăng kích thước 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 4 GB, vì vậy nếu bạn định chạy thêm ứng dụng khác, hãy tính toán tài nguyên cho ứng dụng đó 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 rất quan trọng và dễ bị bỏ qua trên các gói giá rẻ:
grep -m1 -o avx /proc/cpuinfoMongoDB 5.0 trở lên cần 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 khi khởi động và container sẽ khởi động lại liên tục, vì binary thực thi một lệnh mà CPU không hỗ trợ. Các dòng Intel Celeron và Pentium cũ thường là nguyên nhân, cũng như các hypervisor ẩn flag CPU khỏi guest. MongoDB 4.4 không cần AVX và là phương án dự phòng duy nhất, nhưng đó là phiên bản cơ sở dữ liệu mà nhà phát triển không còn vá lỗi nữa. Chuyển sang host có CPU mới hơn là giải pháp tốt hơn. Trên VPS ARM, vấn đề này không xảy ra vì AVX là tập lệnh của x86, và cả hai image đều có bản build cho arm64. Nếu bạn đang cân nhắc 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 phía trên, vì vậy không có gì bên ngoài VPS có thể truy cập vào giao diện quản trị. Hãy forward cổng này qua SSH để chạy trình thiết lập:
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à loại tự ký (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ị, đặt tên cho site và tạm thời bỏ qua bước nhận diệ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 gán cho VPS một địa chỉ private và bind giao diện quản trị vào địa chỉ đó. thiết lập WireGuard VPN trên VPS của bạn và sử dụng Tailscale subnet router đều cung cấp cho bạn một địa chỉ mà chỉ những người trong nhóm mới có thể truy cập. Hãy đổi cổng đã publish thành 10.8.0.1:8443:8443 cho WireGuard, hoặc đổi thành địa chỉ mà Tailscale cấp. Lưu ý: Docker không thể publish trên một địa chỉ chưa tồn tại, vì vậy interface của tunnel phải được khởi tạo trước khi container bắt đầu, nếu không container sẽ bị 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ư
Chỉ có hai cổng cần phải truy cập được từ một site từ xa.
- TCP 8080 là kênh inform, và mọi thiết bị đã được adopt đều kết nối tới nó. 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 thuần là thiết lập bình thường ở đâ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ọ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ỉ sau một lớp mật khẩu.
- UDP 10001 và UDP 1900 là broadcast discovery. Broadcast không truyền qua internet, vì vậy việc mở chúng không có tác dụng gì.
- TCP 8880 và TCP 8843 là các cổng redirect cho guest portal. Chỉ mở chúng nếu bạn chạy guest portal.
- TCP 6789 là cổng kiểm tra tốc độ trên 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, vì vậy nó chỉ tồn tại trên Docker network 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 (default deny) mà các rule đó giả định.
Có một cái bẫy ở đâ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 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 8443Từ chối kết nối (refusal) hoặc timeout là kết quả bạn muốn. 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ó tác dụng, nhưng bind vào địa chỉ nội bộ đơn giản hơn, và lỗi thứ tự rule không thể làm mất hiệu lực của nó.
Còn các trình cài đặt chính chủ của Ubiquiti thì sao?
Ubiquiti phát hành một gói Debian cho Network Application. Nó hoạt động được, 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 này 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 phiên bản 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à phương án được chọ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 cùng một UniFi OS như trên các console phần cứng của họ. Tính đến tháng 8 năm 2026, nó yêu cầu Ubuntu 22.04 hoặc 24.04 trên kiến trúc x86_64, Podman 4.3.1 trở lên với slirp4netns, và yêu cầu tối thiểu 2 vCPU cùng 4 GB RAM, khuyến nghị 4 vCPU và 8 GB RAM. Trình cài đặt nằm sau tài khoản Ubiquiti miễn phí trên trang tải xuống của họ, vì vậy không có URL cố định nào để dán vào hướng dẫn. Nó tạo ra một người dùng hệ thống tên là uosserver và chạy các container dưới quyền người dùng đó. Hãy chọn nó nếu bạn muốn sử dụng gói cài đặt chính chủ từ nhà cung cấp. Hãy chọn stack container nếu bạn muốn tự cố định 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ụ tương tự dưới dạng một gói dịch vụ. Tính đến tháng 8 năm 2026, Official UniFi Cloud Console có giá khởi điểm là 29 đô la mỗi tháng và quản lý tối đa 500 thiết bị UniFi, với việc Ubiquiti chịu trách nhiệm chạy các bản cập nhật và sao lưu. Ứ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 quản lý một site và muốn trả phí thay vì phải tự vá lỗi. 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ột mạng mà bạn kiểm soát và chia sẻ tài nguyên với các dịch vụ khác mà bạn đang chạy. Sự khác biệt về chi phí ở quy mô nhỏ là có thật, 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 hoạt động của người khác, còn VPS là của riêng bạn, bao gồm cả những đêm ổ cứng bị đầy. Nếu máy chủ này vẫn cần phải duy trì, những gì bạn có thể chạy trên VPS là danh sách cầ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. Broadcast không bao giờ vượt ra khỏi mạng nội bộ, nên 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 của VPS, 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 và 4 GB là mức thoải mái. Ứng dụng này bao gồm Java và MongoDB, mỗi thành phần quản lý bộ nhớ riêng: container image mặc định giới hạn Java heap ở 1024 MB, 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 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à 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. Chỉ cần mở TCP 8080 và UDP 3478 cho các site, và bạn có thể giới hạn các cổng này theo địa chỉ IP công cộng của site nếu chúng là IP tĩnh. Hãy nhớ rằng cổng được publish bởi Docker sẽ 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, nên client vẫn kết nối và Wi-Fi vẫn hoạt động. Thứ bị gián đoạn là khả năng quản lý. Bạn sẽ mất dashboard, khả năng thu thập thống kê và các tính năng thời gian thực 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 container image được sử dụng ở đây, chúng nằm trong /config/data/backup/autobackup, đường dẫn này 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à timestamp. Trên một số bản cài đặt mới, thư mục autobackup không tồn tại, khiến backup theo lịch trình 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 đặ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.