راه اندازی UniFi Controller روی VPS
آموزش نصب UniFi Network Application روی VPS با استفاده از Docker و MongoDB. بررسی نیازمندیهای RAM، تنظیمات set-inform برای Layer 3 adoption و لیست پورتهای ضروری.
کارکرد واقعی یک UniFi controller روی یک VPS
یک UniFi controller روی یک VPS، سرور مدیریتی واحدی است که حتی در صورت از دسترس خارج شدن سایتهای تحت مدیریت، همچنان در دسترس باقی میماند. این نرمافزار، UniFi Network Application محصول شرکت Ubiquiti است: یک برنامه مبتنی بر Java که از یک پایگاه داده MongoDB در پسزمینه استفاده میکند. این برنامه وظیفه پیکربندی Access Pointها و سوئیچها، ذخیره آمار آنها و ارائه رابط کاربری مدیریتی را بر عهده دارد. این نرمافزار ترافیک کلاینتها را جابهجا نمیکند.
نکته آخر تعیینکننده محل قرارگیری آن است. اگر controller را روی دستگاهی در داخل همان دفتری که مدیریت میکند قرار دهید، در صورت بروز مشکل، هم شبکه و هم ابزار نظارت بر آن را همزمان از دست میدهید. اما اگر آن را روی یک VPS با آدرس عمومی پایدار قرار دهید، به کار خود ادامه میدهد، دادهها را جمعآوری میکند و میتواند دستگاههای موجود در چندین سایت مختلف را از یک نقطه مدیریت کند. این سرویس به پایداری (uptime) نیاز دارد، نه قدرت پردازشی بالا.
هنگامی که controller آفلاین است، Access Pointها و سوئیچهای adopt شده، همچنان ترافیک را بر اساس پیکربندیهایی که قبلاً دریافت کردهاند، هدایت میکنند. در این حالت، شما داشبورد و آمارها را از دست میدهید، همچنین هر قابلیتی که به فعال بودن controller نیاز دارد—مانند ورود به پورتال مهمان یا سرویس RADIUS (Remote Authentication Dial-In User Service) در صورتی که controller نقش سرور RADIUS شما را داشته باشد—غیرفعال میشود. با این حال، کلاینتها همچنان متصل باقی میمانند.
کنترلر UniFi به چه مقدار RAM نیاز دارد؟
حداقل مقدار مورد نیاز 2 گیگابایت است، اما 4 گیگابایت مقداری است که توصیه میشود تهیه کنید. دو مصرفکننده اصلی حافظه در یک سیستم وجود دارند: Java و MongoDB که هر کدام بهطور مستقل از دیگری حافظه مصرف میکنند.
سقف heap جاوا توسط MEM_LIMIT تعیین میشود که در image کانتینر بهصورت پیشفرض روی 1024 مگابایت تنظیم شده است. نیمه دیگر حافظه مربوط به MongoDB است. موتور ذخیرهسازی WiredTiger آن، اندازه کش خود را بر اساس نیمی از RAM بالای 1 گیگابایت یا 256 مگابایت (هر کدام که بزرگتر باشد) تنظیم میکند. در یک VPS با 2 گیگابایت RAM، این مقدار تقریباً شامل 512 مگابایت کش، 1 گیگابایت heap، حافظه غیر-heap خود JVM و سیستمعامل است. این ترکیب تا زمانی که بار کاری سبک باشد کار میکند، اما در روزهای شلوغ، قابلیت out-of-memory killer در هسته سیستمعامل، یکی از این دو پردازش را متوقف میکند. پس از هر راهاندازی مجدد غیرمنتظره، دستور dmesg -T | grep -i 'killed process' را اجرا کنید تا متوجه شوید آیا این اتفاق رخ داده است یا خیر. اگر 2 گیگابایت RAM دارید، حتماً یک swap file اضافه کنید.
پردازنده (CPU) و دیسک نیاز چندانی به منابع بالا ندارند. یک یا دو vCPU برای مدیریت چند ده دستگاه کافی است. با 20 گیگابایت فضای دیسک شروع کنید و آن را زیر نظر داشته باشید، زیرا حجم پایگاه داده با افزایش تعداد کلاینتها و مدت زمان نگهداری آمار، رشد میکند. یک کنترلر بهتنهایی بخش بزرگی از یک سیستم 4 گیگابایتی را بلااستفاده میگذارد؛ بنابراین اگر قصد دارید سرویس دیگری را در کنار آن میزبانی کنید، منابع را بر اساس نیاز آن سرویس دوم در نظر بگیرید، زیرا PhotoPrism و Immich حداقل RAM بسیار متفاوتی دارند و هر کدام از آنها به حافظه بیشتری نسبت به کنترلر نیاز دارند.
یک ویژگی پردازنده اهمیت زیادی دارد که در پلنهای ارزانقیمت بهراحتی نادیده گرفته میشود:
grep -m1 -o avx /proc/cpuinfoنسخه 5.0 و بالاتر MongoDB به قابلیت AVX (Advanced Vector Extensions) در سختافزار x86_64 نیاز دارد. اگر این دستور خروجی نداشته باشد، mongod در هنگام شروع کار متوقف شده و کانتینر در یک حلقه راهاندازی مجدد گیر میکند، زیرا فایل اجرایی سعی دارد دستوری را اجرا کند که CPU فاقد آن است. پردازندههای قدیمی Intel Celeron و Pentium معمولاً عامل این مشکل هستند؛ همچنین هایپروایزرهایی که پرچمهای CPU را از دید مهمان مخفی میکنند نیز باعث بروز این مشکل میشوند. MongoDB نسخه 4.4 به AVX نیاز ندارد و تنها گزینه جایگزین است، اما این نسخه از پایگاه داده دیگر توسط توسعهدهندگان اصلی پشتیبانی یا وصله نمیشود. انتقال به یک میزبان با CPU جدیدتر، راهکار بهتری است. در VPSهای مبتنی بر ARM این مسئله مطرح نیست، زیرا AVX یک مجموعه دستورالعمل x86 است و هر دو image نسخههای arm64 را ارائه میدهند. اگر بین این دو گزینه مردد هستید، تفاوتهای بین پلنهای VPS مبتنی بر ARM و x86 فراتر از قیمت است.
نصب UniFi Network Application با Docker Compose
استفاده از Docker کمدردسرترین روش است، زیرا به شما اجازه میدهد نسخه MongoDB را دقیقاً مطابق با نسخه پشتیبانیشده توسط برنامه تنظیم کنید، بهجای آنکه به نسخههای موجود در مخازن توزیع لینوکس خود وابسته باشید. اگر Docker هنوز روی سرور نصب نیست، ابتدا Docker را روی VPS نصب کنید.
mkdir -p ~/unifi/config ~/unifi/db
cd ~/unifiبرنامه UniFi پیش از ورود به سیستم، به یک کاربر در MongoDB نیاز دارد. ایمیج رسمی MongoDB در اولین اجرا، هر اسکریپتی را که در /docker-entrypoint-initdb.d پیدا کند، اجرا میکند. این فایل را با نام ~/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" }
]
})
EOFاین اسکریپت فقط زمانی اجرا میشود که دایرکتوری دیتابیس خالی باشد. اگر stack را یکبار با رمز عبور اشتباه اجرا کنید، کاربر با همان رمز اشتباه ساخته میشود و تغییر دادن فایل compose پس از آن بیفایده است، زیرا اسکریپت دیگر اجرا نخواهد شد. نشانه این مشکل این است که کانتینر برنامه خطاهای احراز هویت MongoDB را در لاگ ثبت میکند و رابط وب هرگز بالا نمیآید. در یک نصب تازه، راه حل این است که stack را متوقف کنید، ~/unifi/db را حذف کرده و دوباره شروع کنید.
سپس فایل ~/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-stoppedهر دو تگ ایمیج بهصورت عمدی ثابت (pin) شدهاند. 10.5.67-ls141 نسخه جاری برنامه در آگوست 2026 بود، بنابراین لیست نسخههای ایمیج را چک کنید و هنگام نصب، نسخه جاری را جایگزین کنید. تگ دیتابیس اهمیت بیشتری دارد. MongoDB بهطور خودکار فایلهای داده خود را بین نسخههای اصلی (major versions) ارتقا نمیدهد، بنابراین استفاده از mongo:latest باعث میشود روزی یک نسخه اصلی جدید دریافت کنید که فایلهای موجود را باز نمیکند و کانتینر در یک حلقه بازراهاندازی (restart loop) گیر میافتد. نسخه اصلی را ثابت نگه دارید و ارتقا را آگاهانه انجام دهید. UniFi Network 8.1 و نسخههای بعد از آن از MongoDB 3.6 تا 7.0 پشتیبانی میکنند و نسخه 9.0 پشتیبانی از MongoDB 8.0 را اضافه کرده است.
مقادیر PUID و PGID باید با یک کاربر واقعی روی سیستم میزبان مطابقت داشته باشند، در غیر این صورت مالکیت فایلهای موجود در ./config به شناسهای تعلق میگیرد که اجازه نوشتن در آنها را ندارد. دستور id را اجرا کنید تا شناسه خود را پیدا کنید. مطلب نحوه عملکرد PUID و PGID در ایمیجهای کانتینر توضیح میدهد که عدم تطابق این مقادیر چه مشکلاتی ایجاد میکند.
سرویس را اجرا کرده و لاگها را مشاهده کنید:
docker compose up -d
docker compose ps
docker compose logs -f unifi-network-applicationدستور docker compose ps باید هر دو کانتینر را در وضعیت running نشان دهد. اگر unifi-db در وضعیت restarting گیر کرده است، یا مشکل AVX (که در بالا ذکر شد) وجود دارد یا مشکل دسترسی (permission) در مسیر ./db. پس از اینکه لاگها پایدار شدند، دو پورت شنونده را بررسی کنید:
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/informهر کد وضعیت HTTP نشاندهنده این است که پورت باز است و پاسخ میدهد. کد Connection refused به این معنی است که برنامه هنوز در حال بالا آمدن است (که در اولین اجرا روی یک VPS کوچک ممکن است یک یا دو دقیقه طول بکشد) یا اینکه برنامه اصلاً اجرا نشده است.
دسترسی به رابط کاربری مدیریت بدون افشای آن
پورت 8443 در فایل بالا روی 127.0.0.1 منتشر شده است، بنابراین هیچ منبعی خارج از VPS نمیتواند به رابط کاربری مدیریت دسترسی داشته باشد. برای اجرای ویزارد راهاندازی، آن را از طریق SSH فوروارد کنید:
ssh -L 8443:127.0.0.1:8443 you@vps.example.comآن نشست را باز نگه دارید و به https://127.0.0.1:8443 بروید. گواهی از نوع self-signed است، بنابراین مرورگر یک بار هشدار میدهد. حساب کاربری مدیر را ایجاد کنید، نامی برای سایت انتخاب کنید و فعلاً از مرحله پذیرش دستگاه (device adoption) صرفنظر کنید.
تونل SSH برای یک مدیر مناسب است. برای یک تیم، به VPS یک آدرس خصوصی اختصاص دهید و رابط کاربری را به آن متصل کنید. یک WireGuard VPN روی VPS خود و یک Tailscale subnet router هر دو آدرسی را در اختیار شما قرار میدهند که فقط افراد مجاز شما میتوانند به آن مسیریابی کنند. پورت منتشرشده را برای WireGuard به 10.8.0.1:8443:8443، یا به آدرسی که Tailscale اختصاص میدهد تغییر دهید. یک نکته مهم: Docker نمیتواند روی آدرسی که هنوز وجود ندارد سرویسی را منتشر کند؛ بنابراین رابط تونل باید پیش از شروع container بالا بیاید، در غیر این صورت container با خطای bind مواجه میشود.
چرا یک دستگاه UniFi از راه دور adopt نمیشود
دستگاههای UniFi بهصورت پیشفرض با ارسال broadcast روی پورت UDP 10001 در شبکه محلی، کنترلر خود را پیدا میکنند. از آنجا که broadcast از محدوده LAN خارج نمیشود، دستگاهی که در دفتر کار در شهر دیگری قرار دارد، هرگز کنترلری را که روی یک VPS میزبانی میشود، پیدا نخواهد کرد. این فرآیند، Layer 3 adoption نام دارد و همان جایی است که اکثر کاربران با مشکل مواجه میشوند. دستگاه سالم است و کنترلر نیز بهدرستی کار میکند، اما هیچکس به دستگاه نگفته است که کجا را جستجو کند.
ابتدا باید به کنترلر بگویید چه آدرسی را به دستگاهها اعلام کند. در بخش Settings و قسمت System در کنترلر، تنظیماتی برای inform host با قابلیت override وجود دارد. آن را روی نام دامنه (hostname) عمومی یا IP سرور VPS خود تنظیم کنید. بدون این تنظیم، کنترلر آدرسی را تبلیغ میکند که روی رابط شبکه خودش میبیند؛ که در یک شبکه Docker bridge، یک آدرس خصوصی مانند 172.18.0.3 است. دستگاه این آدرس را دریافت میکند، نمیتواند به آن مسیریابی کند و دوباره به حالت جستجو بازمیگردد.
سپس باید دستگاه را به آن آدرس هدایت کنید. از طریق SSH به دستگاه در LAN راه دور متصل شوید. دستگاهی که با تنظیمات کارخانه است، نام کاربری ubnt و رمز عبور ubnt را میپذیرد:
ssh ubnt@192.168.1.20
set-inform http://vps.example.com:8080/informدر فریمورهای جدیدتر، بهجای shell وارد یک منو میشوید. همان دستور را بهصورت یکخطی اجرا کنید:
ssh ubnt@192.168.1.20 mca-cli-op set-inform http://vps.example.com:8080/informاکنون دستگاه در کنترلر ظاهر شده و آماده adopt شدن است. روی Adopt کلیک کنید تا وضعیت به Adopting تغییر کند. این بخشی است که همه را غافلگیر میکند: معمولاً باید دستور set-inform را برای بار دوم اجرا کنید. دستگاه برای provisioning ریاستارت میشود و به آدرس inform URL که در پیکربندی خودش ذخیره شده بازمیگردد، در حالی که کنترلر هنوز جایگزینی آن را به پایان نرسانده است. اجرای مجدد دستور در حالی که وضعیت Adopting است، انتقال را تکمیل میکند. برای مشاهده inform URL و وضعیت فعلی دستگاه، دستور info را روی آن تایپ کنید.
اگر دستگاه قبلاً توسط کنترلر دیگری adopt شده باشد، دستور set-inform بهتنهایی کارساز نخواهد بود، زیرا دستگاه هنوز اعتبارنامههای (credentials) آن کنترلر قبلی را نگه داشته است. ابتدا آن را با دکمه reset یا با دستور set-default از طریق SSH و با استفاده از اعتبارنامههای قدیمی، به تنظیمات کارخانه بازگردانید.
برای تعداد بیش از چند دستگاه، از DHCP استفاده کنید. گزینه 43 در پروتکل DHCP حاوی مقداری مخصوص فروشنده (vendor-specific) است و دستگاههای UniFi آدرس inform URL را از suboption 2 میخوانند. رشته hex را روی هر سیستم لینوکسی بسازید:
URL="http://vps.example.com:8080/inform"
HEX=$(printf '%s' "$URL" | od -An -tx1 | tr -d ' \n')
printf '02%02x%s\n' "${#URL}" "$HEX"برای http://192.168.3.10:8080/inform، یک رشته 31 بایتی، خروجی 021f687474703a2f2f3139322e3136382e332e31303a383038302f696e666f726d خواهد بود. نتیجه را در فیلد DHCP option 43 روتر خود بهعنوان یک مقدار hex وارد کنید. هر دستگاهی که در آن شبکه بوت شود، آدرس کنترلر را از طریق lease خود دریافت میکند و دیگر نیازی به SSH نیست. راهنماهای قدیمیتر به suboption 1 اشاره دارند، یعنی 0104 که به دنبال آن چهار بایت آدرس IPv4 به صورت hex میآید؛ دستگاهها هنوز هم این فرمت را میپذیرند.
اگر در آن سایت DNS را مدیریت میکنید، راه سوم نیز وجود دارد. دستگاه UniFi هنگام بوت تلاش میکند نام دامنه unifi را resolve کند؛ بنابراین ایجاد یک رکورد A برای unifi که به آدرس VPS شما اشاره کند، باعث میشود دستگاهها بدون نیاز به تنظیمات دستی، adopt شوند. این روش تنها زمانی کارآمد است که شما کنترل resolverای را که دستگاهها واقعاً از آن استفاده میکنند، در اختیار داشته باشید.
کدام پورتهای UniFi را باز کنیم و کدام را خصوصی نگه داریم
تنها دو پورت باید از سایت راه دور در دسترس باشند.
- پورت TCP 8080 کانال inform است و هر دستگاهی که adopt شده باشد به آن متصل میشود. محتوای داخل آن با کلیدی که کنترلر در زمان adoption به دستگاه داده، به صورت AES رمزنگاری میشود؛ به همین دلیل است که HTTP ساده در اینجا تنظیمات استاندارد محسوب میشود.
- پورت UDP 3478 مربوط به STUN (ابزارهای پیمایش نشست برای NAT) است که دستگاهها از آن برای حفظ مسیر بازگشت به کنترلر استفاده میکنند.
بقیه موارد باید روی VPS بسته بمانند.
- پورت TCP 8443 رابط کاربری مدیریت است. این پورتی است که هرگز نباید عمومی باشد. این پورت تنظیمات تمام سایتهایی که کنترلر مدیریت میکند را پشت یک رمز عبور نگه میدارد.
- پورتهای UDP 10001 و UDP 1900 مربوط به کشف از طریق broadcast هستند. پیامهای broadcast از اینترنت عبور نمیکنند، بنابراین باز کردن آنها هیچ فایدهای ندارد.
- پورتهای TCP 8880 و TCP 8843 مربوط به تغییر مسیر پورتال مهمان هستند. آنها را فقط در صورتی باز کنید که پورتال مهمان را اجرا میکنید.
- پورت TCP 6789 برای تست سرعت موبایل و UDP 5514 برای syslog از راه دور است. آنها را تنها زمانی اضافه کنید که از این قابلیتها استفاده میکنید.
- پورت TCP 27117 مربوط به MongoDB است. در فایل compose بالا، دیتابیس هیچ پورتی را منتشر نمیکند، بنابراین فقط در شبکه داخلی Docker وجود دارد. آن را به همین شکل نگه دارید.
اگر سایتهای شما دارای آدرسهای عمومی ثابت هستند، فقط اجازه دسترسی به همانها را بدهید:
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 verboseمطلب اصول ufw برای فایروال VPS تنظیمات پیشفرض deny که این قوانین بر اساس آن فرض شدهاند را پوشش میدهد.
یک تله در اینجا وجود دارد که همیشه کاربران را گرفتار میکند. پورتهای منتشر شده توسط Docker، فایروال ufw را دور میزنند. انتشار یک پورت، قوانین NAT و forwarding را مستقیماً در iptables مینویسد و آن ترافیک در زنجیره اختصاصی Docker فیلتر میشود، نه در زنجیره INPUT که ufw مدیریت میکند. بنابراین ممکن است ufw deny 8443 در ufw status درست به نظر برسد، در حالی که پورت همچنان برای کل دنیا باز است. آن را از یک دستگاه دیگر تست کنید، هرگز از خود VPS تست نگیرید:
nc -vz vps.example.com 8443آنچه شما میخواهید، دریافت خطای refusal یا timeout است. اگر اتصال برقرار شود، پورت عمومی است، صرفنظر از اینکه ufw چه میگوید. راه حل مطمئن همان چیزی است که در فایل compose آمده است: پورت را روی 127.0.0.1 یا روی یک آدرس تونل منتشر کنید تا Docker هرگز آن را به رابط عمومی متصل نکند. یک قانون در زنجیره DOCKER-USER نیز کارساز است، اما اتصال به آدرس داخلی سادهتر است و اشتباه در ترتیب قوانین نمیتواند آن را خنثی کند.
در مورد نصبکنندههای اختصاصی Ubiquiti چطور؟
شرکت Ubiquiti یک بسته Debian برای Network Application منتشر میکند. این بسته کار میکند، اما در نسخههای فعلی Ubuntu پرسشی در مورد MongoDB ایجاد میکند که توزیع دیگر به آن پاسخ نمیدهد: Ubuntu 22.04 و 24.04 هیچ بسته سرور MongoDB ارائه نمیدهند، بنابراین در نهایت مجبور میشوید مخزن اختصاصی MongoDB را اضافه کرده و نسخهها را بهصورت دستی با هم تطبیق دهید. کانتینری که در بالا ذکر شد، این تطبیق را در یک تگ ثابت (pinned tag) انجام میدهد و به همین دلیل است که در این راهنما از آن استفاده شده است.
محصول جدیدتر Ubiquiti برای میزبانی شخصی، UniFi OS Server است که برنامههای UniFi را در کانتینرهای Podman اجرا میکند و همان UniFi OS موجود در کنسولهای سختافزاری آنها را در اختیار شما قرار میدهد. تا اوت 2026، این محصول به Ubuntu 22.04 یا 24.04 با معماری x86_64، نسخه Podman 4.3.1 یا جدیدتر با slirp4netns نیاز دارد و حداقل 2 هسته vCPU با 4 گیگابایت رم را درخواست میکند؛ اگرچه 4 هسته vCPU با 8 گیگابایت رم توصیه میشود. نصبکننده این محصول در صفحه دانلودها پشت یک حساب کاربری رایگان Ubiquiti قرار دارد، بنابراین هیچ URL ثابت و تکخطی برای قرار دادن در راهنما وجود ندارد. این نصبکننده یک کاربر سیستمی به نام uosserver ایجاد میکند و کانتینرها را با همان کاربر اجرا مینماید. اگر میخواهید از بستهبندی رسمی خودِ سازنده استفاده کنید، این گزینه را انتخاب کنید. اگر میخواهید نسخهها را خودتان ثابت نگه دارید و سرور را برای کارهای دیگر آزاد بگذارید، از استک کانتینری استفاده کنید.
محل ذخیره فایلهای پشتیبان UniFi و نحوه انتقال آنها از سرور
کنترلر، فایلهای پشتیبان خود را طبق زمانبندی که در بخش Settings و قسمت backup تنظیم کردهاید، ذخیره میکند. همچنین تعداد فایلهای قابل نگهداری نیز در همانجا تعیین میشود. این فایلها در مسیر /config/data/backup/autobackup داخل کانتینر قرار میگیرند که معادل مسیر ~/unifi/config/data/backup/autobackup روی میزبان (host) است و نام آنها به فرمت autobackup_10.5.67_20260813_1200_1755086400004.unf میباشد.
بررسی کنید که آیا این فایلها واقعاً ایجاد شدهاند:
ls -l ~/unifi/config/data/backup/autobackupخالی بودن این دایرکتوری یک روز پس از تنظیم زمانبندی، یک خطای شناختهشده در نصبهای تازه کانتینر است. برنامه انتظار دارد دایرکتوری autobackup از قبل وجود داشته باشد و خود آن را ایجاد نمیکند؛ بنابراین، وظیفه زمانبندیشده (scheduled job) بدون هیچ خطایی، فایلی تولید نمیکند. آن را با همان کاربری که کانتینر تحت آن اجرا میشود ایجاد کنید و سپس منتظر اجرای بعدی بمانید:
mkdir -p ~/unifi/config/data/backup/autobackup
docker compose restart unifi-network-applicationیک فایل .unf حاوی پیکربندی سایت و حسابهای کاربری مدیر است، بنابراین با آن مانند یک کلید امنیتی رفتار کنید. نسخههایی از آن را به سیستمی که تحت کنترل شماست منتقل کرده و محرمانه نگه دارید:
rsync -av you@vps.example.com:~/unifi/config/data/backup/autobackup/ ~/unifi-backups/بازیابی (restore) تنها یک مرحله دارد. صفحه اول ویزارد راهاندازی در یک نصب جدید، گزینه بازیابی از فایل پشتیبان را ارائه میدهد و در یک کنترلر در حال اجرا نیز، این کار از همان صفحه تنظیمات انجام میشود. بازیابی باید روی همان نسخه یا نسخهای جدیدتر انجام شود. فایل پشتیبانی که توسط نسخه جدیدتری از برنامه ایجاد شده باشد، در نسخههای قدیمیتر پذیرفته نمیشود؛ به همین دلیل توصیه میشود شماره نسخه را همراه با فایل پشتیبان یادداشت کنید.
چه مواردی ممکن است با ارتقای کنترلر دچار اختلال شوند
پیش از هر ارتقا، یک نسخه پشتیبان دستی تهیه کرده و آن را دانلود کنید. سپس:
docker compose pull
docker compose up -d
docker compose logs -f unifi-network-applicationپایگاه داده اولین بخشی است که دچار مشکل میشود. تغییر تگ mongo به یک نسخه اصلی (major version) جدید در همان ویرایشی که برنامه را ارتقا میدهید، سریعترین راه برای از کار افتادن کنترلر است؛ زیرا MongoDB فایلهای داده مربوط به یک نسخه اصلی متفاوت را بدون طی کردن مراحل ارتقای مرحلهبندیشده باز نمیکند. برنامه را بهتنهایی ارتقا دهید. MongoDB را بهصورت جداگانه و هر بار تنها یک نسخه اصلی ارتقا دهید و حتماً یک نسخه پشتیبان تازه در اختیار داشته باشید.
حافظه مورد بعدی است. یک نسخه جدیدتر معمولاً به Heap بزرگتری نیاز دارد. اگر برنامه شروع به کار کرد، چند دقیقه اجرا شد و سپس متوقف شد، مقادیر MEM_LIMIT و MEM_STARTUP را به 1536 یا 2048 افزایش دهید و سرویس را مجدداً راهاندازی کنید. دستور dmesg -T | grep -i 'killed process' روی میزبان تأیید میکند که آیا هسته سیستمعامل (kernel) عامل متوقف کردن آن بوده است یا خیر.
سفتافزار (firmware) دستگاهها ریسکی است که معمولاً فراموش میشود. پس از اینکه کنترلر خود را ارتقا داد، پیشنهاد ارتقای سفتافزار برای دستگاههای متصل (adopted) ارائه میدهد. این کار را در همان نشست (session) انجام ندهید. اگر ارتقای دستگاه و ارتقای کنترلر همپوشانی داشته باشند و ارتباط بین آنها قطع شود، دستگاه ممکن است در وضعیت نیمهپیکربندیشده باقی بماند و مجبور شوید برای دسترسی به سختافزاری که در ساختمان دیگری قرار دارد، به set-inform از طریق SSH متوسل شوید.
بازه زمانی ارتقا از آنچه به نظر میرسد ملایمتر است. دستگاهها در حین راهاندازی مجدد کنترلر به انتقال ترافیک ادامه میدهند، بنابراین کاربران متوجه قطعی نمیشوند. آنچه متوقف میشود، پورتال مهمان و RADIUS (در صورتی که کنترلر آنها را ارائه دهد) است؛ بنابراین زمانی را انتخاب کنید که از این سرویسها استفاده نمیشود. کنترلری که در ساعت 3 بامداد بیسروصدا از کار میافتد ارزش مانیتور شدن دارد، پس یک مانیتور وضعیت Uptime Kuma را روی پورت 8080 تنظیم کنید تا شما را مطلع سازد.
جایگزین صادقانه: کنسول میزبانیشده Ubiquiti
شرکت Ubiquiti همین وظیفه را به عنوان یک سرویس ارائه میدهد. از اوت 2026، کنسول رسمی UniFi Cloud با قیمت 29 دلار در ماه شروع میشود و تا 500 دستگاه UniFi را مدیریت میکند، در حالی که بهروزرسانیها و پشتیبانگیریها توسط Ubiquiti انجام میشود. برنامهای که خودتان میزبانی کردهاید رایگان است و هیچ حق اشتراکی ندارد.
اگر تنها یک سایت را مدیریت میکنید و ترجیح میدهید به جای مدیریت وصلهها هزینه پرداخت کنید، کنسول میزبانیشده را انتخاب کنید. اگر چندین سایت را مدیریت میکنید، یا میخواهید کنترلر در شبکهای باشد که خودتان آن را کنترل میکنید و با سایر سرویسهایی که اجرا میکنید در یک سرور مشترک باشد، یک VPS انتخاب کنید. تفاوت هزینه در مقیاس کوچک واقعی است، اما تنها موردی نیست که باید سنجیده شود: کنسول میزبانیشده به معنای تکیه بر آپتایم دیگران است، در حالی که VPS متعلق به خودتان است، از جمله شبی که دیسک آن پر میشود. اگر قرار است این سرور در هر صورت هزینههای خود را پوشش دهد، چه چیزهای دیگری میتوانید روی یک VPS اجرا کنید فهرستی است که باید در ادامه مطالعه کنید.
FAQ
چرا دستگاه UniFi من به کنترلر روی VPS متصل (Adopt) نمیشود؟
دستگاهها کنترلرها را از طریق broadcast روی پورت UDP 10001 پیدا میکنند و چون broadcast از شبکه محلی خارج نمیشود، دستگاه در یک سایت راه دور نمیتواند کنترلر را در اینترنت عمومی پیدا کند. در تنظیمات سیستم کنترلر، گزینه inform host override را روی نام دامنه (hostname) VPS خود تنظیم کنید، سپس با دستور ssh ubnt@<device-ip> و به دنبال آن set-inform http://vps.example.com:8080/inform، دستگاه را به سمت آن هدایت کنید. اگر دستگاه در وضعیت Adopting باقی ماند، در همان حال دوباره دستور set-inform را اجرا کنید. اگر کنترلر دیگری قبلاً آن را Adopt کرده است، ابتدا آن را به تنظیمات کارخانه بازگردانید، زیرا دستگاه همچنان اعتبارنامههای کنترلر قبلی را در خود نگه میدارد.
کنترلر UniFi خود-میزبانی (self-hosted) به چه مقدار RAM نیاز دارد؟
مقدار 2 GB حداقلِ مورد نیاز برای کارکرد است و 4 GB شرایط مطلوبی را فراهم میکند. این برنامه از Java و MongoDB تشکیل شده است و هر دو حافظه خود را جداگانه مدیریت میکنند: image کانتینر بهطور پیشفرض Java heap را روی 1024 MB محدود میکند، در حالی که کش WiredTiger در MongoDB نیمی از RAM بالای 1 GB را اشغال میکند. در معماری x86_64، همچنین با دستور grep -m1 -o avx /proc/cpuinfo تأیید کنید که CPU از AVX پشتیبانی میکند، زیرا MongoDB نسخه 5.0 و بالاتر بدون آن اجرا نمیشود و کانتینر دیتابیس در یک حلقه تکرار ریاستارت میشود.
آیا باید پورت 8443 را روی اینترنت باز بگذارم؟
خیر. پورت 8443 رابط مدیریتی است و تنظیمات تمام سایتهایی که کنترلر مدیریت میکند در آن قرار دارد. آن را روی 127.0.0.1 منتشر کنید و با استفاده از ssh -L 8443:127.0.0.1:8443 you@vps.example.com به آن دسترسی داشته باشید، یا آن را به یک آدرس WireGuard یا Tailscale محدود کنید. تنها پورتهای TCP 8080 و UDP 3478 باید از سایتهای شما در دسترس باشند و اگر آدرسهای عمومی سایتها ثابت (static) هستند، میتوانید دسترسی به این پورتها را فقط به همان آدرسها محدود کنید. به یاد داشته باشید که پورت منتشر شده توسط Docker توسط ufw فیلتر نمیشود، بنابراین به جای اعتماد به ufw status، تست را از یک ماشین خارجی انجام دهید.
آیا در صورت از دسترس خارج شدن کنترلر VPS، شبکه من از کار میافتد؟
خیر. اکسسپوینتها و سوییچهای Adopt شده، ترافیک را با استفاده از پیکربندی که قبلاً توسط کنترلر ارسال شده است هدایت میکنند، بنابراین کلاینتها متصل میمانند و Wi-Fi به کار خود ادامه میدهد. آنچه متوقف میشود، مدیریت شبکه است. شما داشبورد و جمعآوری آمار را از دست میدهید، همچنین هر قابلیت زندهای که کنترلر ارائه میدهد، مانند احراز هویت در پورتال مهمان یا RADIUS (در صورتی که کنترلر سرور RADIUS باشد)، غیرفعال میشود.
کنترلر UniFi پشتیبانهای خودکار را کجا ذخیره میکند؟
در image کانتینری که اینجا استفاده شده است، این فایلها در /config/data/backup/autobackup قرار میگیرند که به مسیر دادههای شما به اضافه data/backup/autobackup روی میزبان (host) نگاشت شده است، به صورت فایلهای .unf که با نام نسخه و یک timestamp نامگذاری شدهاند. در برخی نصبهای تازه، دایرکتوری autobackup وجود ندارد و در نتیجه پشتیبانگیری زمانبندیشده بدون گزارش خطا، فایلی ایجاد نمیکند. بنابراین یک روز پس از تنظیم زمانبندی، محتویات آن دایرکتوری را بررسی کنید و اگر خالی بود، خودتان آن را ایجاد کنید. فایلها را از روی VPS کپی کنید، زیرا یک .unf حاوی پیکربندی سایت و حسابهای کاربری مدیر است.