ورود به پنل ثبت‌ نام

نصب Open WebUI روی سرور ابری؛ رابط چت مدل‌های محلی

نصب Open WebUI روی سرور ابری و اتصال آن به Ollama؛ یک رابط چت چندکاربره برای مدل‌های زبانی متن‌باز، پشت پراکسی معکوس Nginx و گواهی SSL رایگان.

تیم ابر سپهر 12 دقیقه مطالعه
نصب Open WebUI روی سرور ابری؛ رابط چت مدل‌های محلی
در این مقاله

اجرای مدل‌های زبانی روی سرور خودتان یک نیمه‌ی کار است؛ نیمه‌ی دیگر، رابطی است که بقیه‌ی تیم هم بتوانند از آن استفاده کنند. Ollama یک API می‌دهد که برای برنامه‌نویس عالی است اما برای همکاری که می‌خواهد فقط سؤالی بپرسد یا فایلی را خلاصه کند، کافی نیست. نصب Open WebUI روی سرور ابری دقیقاً همین شکاف را پر می‌کند: یک رابط چت شبیه به سرویس‌های تجاری، با مدیریت کاربران، تاریخچه‌ی گفتگو، آپلود سند و امکان جابه‌جایی میان مدل‌ها.

Open WebUI یک برنامه‌ی وب متن‌باز است که جلوی Ollama (یا هر بک‌اندی با API سازگار با OpenAI) می‌نشیند. همه‌چیز روی زیرساخت خودتان می‌ماند: پرامپت‌ها، تاریخچه‌ی گفتگوها و سندهایی که کاربران آپلود می‌کنند، هیچ‌کدام به سرویس بیرونی نمی‌روند. برای تیم‌هایی که با اسناد داخلی یا داده‌ی مشتری کار می‌کنند، همین یک ویژگی تفاوت میان «می‌شود استفاده کرد» و «نمی‌شود» است.

در این راهنما Open WebUI را با داکر روی Ubuntu 24.04/26.04 نصب می‌کنیم، به Ollama که پیش‌تر روی همان سرور نصب شده وصلش می‌کنیم، پشت پراکسی معکوس Nginx می‌گذاریم و با گواهی رایگان Let's Encrypt امن می‌کنیم.

پیش‌نیازها

  • یک سرور ابری با Ubuntu 24.04/26.04 و دسترسی root.
  • Ollama نصب‌شده و در حال اجرا روی همین سرور. اگر هنوز نصبش نکرده‌اید، ابتدا راهنمای نصب Ollama روی سرور ابری را دنبال کنید.
  • داکر نصب‌شده؛ در غیر این صورت راهنمای نصب داکر روی اوبونتو را ببینید.
  • دست‌کم ۴ هسته پردازنده و ۸ گیگابایت حافظه. خودِ Open WebUI سبک است (کمتر از یک گیگابایت)، اما مدل باید کامل در حافظه جا شود و بار اصلی روی Ollama است.
  • یک سابدامین مثل chat.domain.com با رکورد A به آی‌پی سرور.

تمام دستورها با کاربر root اجرا می‌شوند.

گام ۱: آماده‌سازی Ollama برای دسترسی از کانتینر

در راهنمای Ollama، سرویس را روی 127.0.0.1:11434 نگه داشتیم تا از اینترنت در دسترس نباشد. حالا مشکلی پیش می‌آید: Open WebUI داخل یک کانتینر داکر اجرا می‌شود و 127.0.0.1 برای کانتینر یعنی خودِ کانتینر، نه سرور. پس Ollama باید روی رابطی گوش دهد که کانتینر هم آن را ببیند:

systemctl edit ollama.service

و در بخش ویرایش‌پذیر:

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

سپس سرویس را بارگذاری مجدد کنید:

systemctl daemon-reload
systemctl restart ollama
ss -tlnp | grep 11434

خروجی ss باید نشان دهد که سرویس روی 0.0.0.0:11434 گوش می‌دهد. این تغییر به این معنی نیست که API شما روی اینترنت باز شده؛ فایروال همچنان جلوی دسترسی بیرونی را می‌گیرد و در گام بعد فقط برای شبکه‌ی داکر استثنا می‌گذاریم.

گام ۲: تنظیم فایروال برای شبکه‌ی داکر

اگر UFW را طبق راهنمای امن‌سازی سرور لینوکس با سیاست deny incoming تنظیم کرده باشید، ترافیک کانتینر به سمت سرور هم مسدود می‌شود. یک قاعده‌ی دقیق برای همین مسیر اضافه می‌کنیم:

ufw allow in on docker0 to any port 11434 proto tcp
ufw reload
ufw status verbose

این قاعده فقط به ترافیکی که از رابط docker0 می‌آید (یعنی کانتینرهای همین سرور) اجازه‌ی رسیدن به پورت ۱۱۴۳۴ را می‌دهد. از اینترنت، این پورت همچنان بسته است.

پورت ۱۱۴۳۴ را هرگز با ufw allow 11434 باز نکنید. API اولاما هیچ احراز هویتی ندارد؛ هر کسی که به آن برسد می‌تواند مدل‌های شما را اجرا کند و منابع سرور را مصرف کند.

گام ۳: اجرای کانتینر Open WebUI

ابتدا یک کلید تصادفی برای امضای نشست‌ها می‌سازیم:

openssl rand -hex 32

خروجی را نگه دارید. حالا کانتینر را اجرا می‌کنیم:

docker run -d --name open-webui --restart unless-stopped \
  -p 127.0.0.1:3000:8080 \
  --add-host=host.docker.internal:host-gateway \
  -v open-webui:/app/backend/data \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -e WEBUI_SECRET_KEY=PASTE_YOUR_RANDOM_KEY \
  -e TZ=Asia/Tehran \
  ghcr.io/open-webui/open-webui:main

اجزای مهم این دستور:

  • -p 127.0.0.1:3000:8080 برنامه را فقط روی خود سرور منتشر می‌کند. اگر -p 3000:8080 بنویسید، داکر قاعده‌ای در iptables می‌سازد که از کنار UFW رد می‌شود و پنل شما بدون HTTPS مستقیم روی اینترنت قرار می‌گیرد.
  • --add-host=host.docker.internal:host-gateway نام host.docker.internal را داخل کانتینر به آی‌پی سرور روی شبکه‌ی داکر ترجمه می‌کند؛ این همان مسیری است که در گام دوم در فایروال بازش کردیم.
  • -v open-webui:/app/backend/data والیوم داده‌هاست: کاربران، تاریخچه‌ی گفتگوها، تنظیمات و اسناد آپلودشده اینجا می‌مانند. بدون آن، با هر به‌روزرسانی همه‌چیز پاک می‌شود.
  • WEBUI_SECRET_KEY کلید امضای توکن‌های ورود است. اگر آن را تعیین نکنید، در اولین اجرا یک کلید تصادفی ساخته می‌شود؛ تعیین صریح آن باعث می‌شود با بازسازی کانتینر، کاربران از حساب خود بیرون نیفتند.

چند لحظه بعد، سلامت اجرا را بررسی کنید:

docker logs -f open-webui

اولین بالا آمدن ممکن است یکی دو دقیقه طول بکشد، چون برنامه پایگاه داده‌ی داخلی خود را می‌سازد.

گام ۴: پیکربندی Nginx به‌عنوان پراکسی معکوس

Nginx را نصب و فایل سایت را می‌سازیم:

apt install -y nginx
nano /etc/nginx/sites-available/chat.domain.com

با این محتوا:

server {
    listen 80;
    server_name chat.domain.com;

    # آپلود سند برای پرسش‌وپاسخ روی فایل‌ها
    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # پاسخ مدل به‌صورت جریانی و زنده می‌آید
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;

        # مدل‌های بزرگ روی CPU کند پاسخ می‌دهند
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}

سه تنظیم اینجا حیاتی‌اند و هرکدام یک خرابی مشخص را جلوگیری می‌کنند:

  • بدون Upgrade/Connection رابط بالا می‌آید ولی پاسخ مدل کلمه‌به‌کلمه نمایش داده نمی‌شود و گاهی گفتگو معلق می‌ماند.
  • بدون proxy_buffering off پاسخ در Nginx بافر می‌شود و کاربر تا پایان تولید کامل متن چیزی نمی‌بیند؛ تجربه‌ای که شبیه هنگ‌کردن است.
  • proxy_read_timeout پیش‌فرض ۶۰ ثانیه است. یک مدل ۸ میلیاردی روی CPU به‌راحتی از این زمان عبور می‌کند و پاسخ نیمه‌کاره قطع می‌شود.

حالا سایت را فعال و پیکربندی را بررسی کنید:

ln -s /etc/nginx/sites-available/chat.domain.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
ufw allow 'Nginx Full'

گام ۵: فعال‌سازی SSL با Let's Encrypt

apt install -y certbot python3-certbot-nginx
certbot --nginx -d chat.domain.com

Certbot گواهی را صادر می‌کند، فایل Nginx را برای HTTPS ویرایش می‌کند و ریدایرکت پورت ۸۰ به ۴۴۳ را می‌سازد. تمدید خودکار با یک تایمر systemd انجام می‌شود؛ برای آزمودنش:

certbot renew --dry-run

HTTPS اینجا یک تشریفات نیست: نشست ورود کاربران و کل متن گفتگوها از این کانال عبور می‌کنند.

گام ۶: ساخت حساب مدیر و بستن ثبت‌نام آزاد

حالا https://chat.domain.com را باز کنید. نخستین حسابی که ساخته شود، مدیر کل سیستم است؛ همین حالا و پیش از آن‌که آدرس را با کسی به اشتراک بگذارید این کار را انجام دهید.

تا وقتی حساب مدیر ساخته نشده، هر کسی که آدرس را بداند می‌تواند مالک نمونه‌ی شما شود. اگر سرور را در فضای عمومی رها کرده‌اید و مطمئن نیستید چه کسی اول وارد شده، کانتینر و والیوم را پاک کنید و از نو شروع کنید.

پس از ساخت حساب مدیر، از مسیر Admin Panel → Settings → General گزینه‌ی ثبت‌نام کاربران جدید را ببندید و کاربران را دستی اضافه کنید. اگر ترجیح می‌دهید این سیاست در خود کانتینر تثبیت شود، متغیر زیر را به دستور docker run اضافه کنید:

-e ENABLE_SIGNUP=false

گام ۷: دانلود مدل و انتخاب اندازه‌ی مناسب

Open WebUI مدل‌ها را از Ollama می‌خواند، پس هر مدلی که با ollama pull بگیرید در فهرست کشویی رابط ظاهر می‌شود:

ollama pull qwen2.5:7b
ollama list

قاعده‌ی انتخاب مدل همان است که در راهنمای Ollama گفتیم: مدل باید کامل در RAM جا شود، وگرنه سیستم سراغ swap می‌رود و پاسخ‌ها به‌شکل غیرقابل‌استفاده‌ای کند می‌شوند.

حافظه‌ی سرور مدل پیشنهادی مناسب برای
۴ گیگابایت llama3.2:3b پاسخ‌های کوتاه، آزمایش اولیه
۸ گیگابایت qwen2.5:7b چت عمومی، خلاصه‌سازی متن
۱۶ گیگابایت qwen2.5:14b پرسش‌وپاسخ روی اسناد، کیفیت بالاتر

پرسش‌وپاسخ روی اسناد داخلی

یکی از دلایل اصلی راه‌اندازی چنین سرویسی روی سرور خودی، همین بخش است: Open WebUI اجازه می‌دهد فایل‌ها را در یک مخزن دانش (Knowledge) آپلود کنید و بعد در گفتگو به آن‌ها ارجاع دهید. متن سندها روی همان والیومی که در گام سوم ساختیم پردازش و ذخیره می‌شود و به هیچ سرویس بیرونی نمی‌رود؛ برای قراردادها، مستندات داخلی یا گزارش‌های مالی، این تفاوت تعیین‌کننده است.

دو نکته‌ی عملی: اندازه‌ی مجاز آپلود را در گام چهارم با client_max_body_size روی ۱۰۰ مگابایت گذاشتیم؛ اگر با فایل‌های بزرگ‌تر کار می‌کنید همان‌جا افزایشش دهید. و پردازش اولیه‌ی سندهای بزرگ روی CPU زمان‌بر است، پس اگر آپلود طول کشید، پیش از تغییر تنظیمات یک بار docker logs -f open-webui را ببینید.

مدیریت کاربران و دسترسی مدل‌ها

هر کاربر جدید در وضعیت pending می‌ماند تا مدیر او را تأیید کند؛ این رفتار پیش‌فرض عمداً محافظه‌کارانه است. در پنل مدیریت می‌توانید برای هر کاربر نقش تعیین کنید و مشخص کنید کدام مدل‌ها در دسترس چه کسانی باشند. اگر مدل بزرگی دارید که اجرای آن منابع زیادی می‌خواهد، محدود کردنش به چند کاربر خاص ساده‌ترین راه کنترل مصرف است.

نکته‌ای که در محیط چندکاربره اهمیت پیدا می‌کند: Ollama درخواست‌ها را به‌صورت موازی-محدود پردازش می‌کند و روی CPU، دو کاربر هم‌زمان یعنی تقریباً دو برابر زمان انتظار. اگر قرار است چند نفر به‌طور جدی از سیستم استفاده کنند، حافظه و پردازنده را از کنترل پنل ابر سپهر ارتقا دهید یا سراغ سرور مجهز به GPU بروید.

نگهداری: به‌روزرسانی و بک‌آپ

به‌روزرسانی Open WebUI یعنی گرفتن ایمیج جدید و ساختن دوباره‌ی کانتینر. چون داده‌ها در والیوم open-webui هستند، گفتگوها و کاربران حفظ می‌شوند:

docker pull ghcr.io/open-webui/open-webui:main
docker stop open-webui && docker rm open-webui
# سپس همان دستور docker run گام سوم را دوباره اجرا کنید

چون تگ main است و نه یک نسخه‌ی ثابت، هر بار docker pull ممکن است تغییرهای قابل‌توجهی بیاورد؛ پیش از به‌روزرسانی یک اسنپ‌شات از کنترل پنل ابر سپهر بگیرید تا در صورت بروز مشکل، چند دقیقه‌ای به وضعیت قبل برگردید.

بک‌آپ والیوم هم با یک کانتینر موقت انجام می‌شود:

docker run --rm -v open-webui:/data -v /root:/backup busybox \
  tar czf /backup/open-webui-backup.tar.gz -C /data .
کار دستور چه زمانی
مشاهده لاگ docker logs -f open-webui هنگام عیب‌یابی
بررسی اتصال به Ollama curl http://127.0.0.1:11434/api/tags وقتی فهرست مدل‌ها خالی است
راه‌اندازی مجدد docker restart open-webui پس از تغییر تنظیمات
به‌روزرسانی docker pull و اجرای دوباره کانتینر ماهانه
بک‌آپ داده‌ها tar از والیوم یا اسنپ‌شات پنل هفتگی

اگر فهرست مدل‌ها در رابط خالی بود، تقریباً همیشه مقصر یکی از این دو است: نبودن قاعده‌ی docker0 در فایروال یا اشتباه در OLLAMA_BASE_URL. با docker exec -it open-webui curl http://host.docker.internal:11434/api/tags می‌توانید مسیر را از داخل کانتینر آزمایش کنید.

جمع‌بندی

با نصب Open WebUI روی سرور ابری، مدل‌های محلی شما از یک API خام به سرویسی تبدیل می‌شوند که کل تیم می‌تواند از آن استفاده کند؛ بدون آن‌که حتی یک پرامپت از سرور خارج شود.

سه تصمیمی که بیشترین تفاوت را می‌سازند: منتشر کردن کانتینر فقط روی 127.0.0.1 و عبور دادن ترافیک از Nginx، باز کردن پورت Ollama فقط روی رابط docker0، و ساختن فوری حساب مدیر پیش از اشتراک‌گذاری آدرس.

قدم بعدی طبیعی، اتصال همین مدل‌ها به گردش‌کارهای خودکار است؛ می‌توانید Ollama را به n8n وصل کنید. و اگر هنوز سرور مناسبی ندارید، از صفحه خرید سرور ابری با حافظه‌ی کافی برای مدل موردنظرتان شروع کنید.

مقالات مرتبط