SSD Nodes Learn 🎉 VPS từ $4.99/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

So sánh Open WebUI alternatives cho VPS có IP public

So sánh Open WebUI, LibreChat, Hollama và OrionChat trên VPS: RAM còn lại cho model, login, Ollama từ xa và chi phí upkeep khi mở IP public.

Open WebUI alternative nào phù hợp với VPS

Các alternative của Open WebUI hầu như luôn được so sánh trên laptop, nơi RAM rẻ và không có dịch vụ nào lắng nghe trên địa chỉ public. VPS thay đổi cả hai điều này, nên thứ tự lựa chọn cũng thay đổi. Open WebUI vẫn là lựa chọn mặc định phù hợp ngay khi có người thứ hai đăng nhập, vì nó có sẵn user account thực và admin panel. Các project nhẹ hơn có lợi thế khi giao diện phải cạnh tranh với model để giành phần RAM cuối cùng. Cái giá của lợi thế đó là authentication: chúng không có authentication.

Toàn bộ nội dung dưới đây dựa trên tài liệu riêng của từng project, được xem vào tháng 8 năm 2026. Bốn tiêu chí này chỉ trở nên quan trọng khi server có thể truy cập từ internet.

Bốn khía cạnh chỉ thực sự quan trọng khi dùng IP public

  • Bộ nhớ dùng cùng model. Model server là tiến trình tốn tài nguyên nhất trên máy. Mỗi megabyte mà interface giữ lại là một megabyte model không thể sử dụng.
  • Xác thực. Một số project có user account và role. Một số project khác giả định chúng là thứ duy nhất đang chạy trên laptop của bạn và hoàn toàn không có login.
  • Inference từ xa. UI chỉ có thể kết nối đến 127.0.0.1:11434 sẽ buộc model phải chạy trên cùng máy với interface.
  • Công việc bảo trì. Một container dùng file SQLite là một loại công việc khác hoàn toàn so với 6 container dùng MongoDB và một vector database phía sau.

Model còn bao nhiêu RAM cho interface

Interface không phải thành phần lớn nhất trên máy. Model mới là thành phần chiếm nhiều RAM nhất. Kích thước download được công bố cho bạn biết mức tối thiểu, vì weights phải luôn nằm trong RAM khi model tạo câu trả lời. Mức sử dụng bộ nhớ thực tế sẽ cao hơn kích thước download sau khi cấp phát context cache.

ChartPublished download size of common Ollama models, August 2026
The data behind this chart
[
  {
    "label": "llama3.2:3b",
    "download_gb": "2.0"
  },
  {
    "label": "qwen3:4b",
    "download_gb": "2.5"
  },
  {
    "label": "gemma3:4b",
    "download_gb": "3.3"
  },
  {
    "label": "qwen3:8b",
    "download_gb": "5.2"
  }
]

Đây là các số liệu do các trang thư viện Ollama hiển thị vào tháng 8 năm 2026. Đây là kích thước được công bố, không phải số đo thực tế. Trên VPS 4 GB, qwen3:4b có kích thước 2.5 GB sẽ chỉ còn dưới 1.5 GB cho operating system và mọi thành phần khác. Context cache sẽ tiếp tục chiếm thêm dung lượng khi cuộc hội thoại dài hơn. qwen3:8b có kích thước 5.2 GB hoàn toàn không chạy được trên máy đó. Các bài tổng hợp về laptop thường không đề cập tình huống này. Đây là lúc một chat interface chiếm vài trăm megabyte có thể quyết định model có chạy được hay không.

Đừng tin tuyệt đối vào bất kỳ con số nào trong các bài tổng hợp, kể cả bài này. Hãy đo bằng cách chạy docker stats --no-stream sau khoảng một giờ sử dụng thực tế, không phải một phút sau khi container khởi động, vì phần bộ nhớ quan trọng chỉ được cấp phát khi dùng lần đầu.

Open WebUI: vẫn là lựa chọn mặc định cho nhiều người dùng

Open WebUI chạy từ một image và lưu dữ liệu trong một volume.

docker run -d -p 127.0.0.1:3000:8080 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main

Lệnh trong README của dự án publish -p 3000:8080, cổng này lắng nghe trên mọi interface. Prefix 127.0.0.1: giữ dịch vụ chỉ trên loopback. Trên VPS, prefix đó quan trọng hơn mọi phần khác trong dòng lệnh, vì Docker tự ghi các rule iptables và cổng đã publish sẽ bỏ qua rule deny của ufw.

Truy cập trang qua tunnel hoặc proxy, cả hai cách đều được mô tả bên dưới, rồi tạo tài khoản đầu tiên. Tài khoản đó trở thành administrator. Các tài khoản đăng ký sau sẽ được tạo với role pending, là giá trị mặc định được tài liệu hóa tại DEFAULT_USER_ROLE. Vì vậy, người lạ truy cập được trang vẫn không thể dùng model của bạn nếu chưa được administrator phê duyệt.

Open WebUI dùng nhiều memory hơn các dự án bên dưới vì nó có nhiều chức năng hơn. Trang hiệu năng của dự án cũng nêu rõ các thành phần gây tốn tài nguyên. Embedding engine mặc định tải một model sentence-transformers bên trong container, với mức sử dụng được tài liệu hóa khoảng 500 MB cho mỗi worker process. Đặt RAG_EMBEDDING_ENGINE=ollama sẽ chuyển công việc đó cho model server bạn đã chạy sẵn. AUDIO_STT_ENGINE=webapi ngăn việc tải model speech-to-text cục bộ. Khi dùng SQLite và không đặt DATABASE_POOL_SIZE, pool sẽ fallback về một kích thước nội bộ lớn. Mỗi connection còn tạo page cache và memory map riêng. Vì vậy, trên máy có ít tài nguyên, hãy đặt DATABASE_POOL_SIZE=8DATABASE_SQLITE_PRAGMA_MMAP_SIZE=0. ENABLE_AUTOCOMPLETE_GENERATION=False ngăn interface yêu cầu model tạo completion khi người dùng vẫn đang nhập.

LibreChat: nhiều người dùng, có stack phía sau

git clone https://github.com/danny-avila/LibreChat.git
cd LibreChat
cp .env.example .env
docker compose up -d

Giao diện lắng nghe trên cổng 3080. LibreChat phù hợp khi bạn cần một hệ thống quản lý danh tính thay vì chỉ một hộp đăng nhập: tài liệu của dự án mô tả cách đăng nhập bằng LDAP và OAuth2, đồng thời tích hợp admin panel để quản lý user và role. Tính năng này đi kèm một stack.

ChartContainers a default install adds, not counting the model server
The data behind this chart
[
  {
    "label": "OrionChat",
    "containers": 0,
    "notes": "static files, served by a web server you already run"
  },
  {
    "label": "Hollama",
    "containers": 1,
    "notes": "one container serving a browser app"
  },
  {
    "label": "Open WebUI",
    "containers": 1,
    "notes": "application and SQLite in one image"
  },
  {
    "label": "LibreChat",
    "containers": 6,
    "notes": "api, admin panel, MongoDB, Meilisearch, pgvector, RAG API"
  }
]

File compose mặc định khởi động 6 service: api, admin panel, MongoDB, Meilisearch, pgvector, RAG API. Không service nào trong số đó là model. MongoDB và pgvector đều cần phần memory riêng. Trên máy 4 GB, đó là phần memory mà model cần.

Nâng cấp được thực hiện bằng thao tác git. Đây là phần thường bị làm sai.

docker compose down
git pull
docker compose pull
docker compose up -d

git pull sẽ dừng với conflict nếu bạn đã sửa docker-compose.yml đang được git track. Khi đó quá trình nâng cấp chỉ được áp dụng một phần. Đặt các thay đổi của bạn vào docker-compose.override.yml, vì project cung cấp file này cho mục đích đó, và lưu secret trong .env. Cả hai file đều không được git track, nên git pull sẽ giữ nguyên chúng.

Trỏ LibreChat đến model server của bạn bằng một custom endpoint trong librechat.yaml.

endpoints:
  custom:
    - name: "Ollama"
      apiKey: "ollama"
      baseURL: "http://model-host:11434/v1/"
      models:
        default: ["llama3.2"]
        fetch: true
      titleConvo: true
      titleModel: "current_model"
      modelDisplayLabel: "Ollama"

Thay model-host bằng địa chỉ của máy đang chạy Ollama. Trường apiKey phải có mặt dù Ollama bỏ qua giá trị của trường này, nên dùng placeholder là được. Nếu LibreChat chạy trong Docker còn Ollama chạy trên cùng máy, localhost bên trong container trỏ đến chính container đó. Khi đó, hãy dùng host.docker.internal.

Hollama và OrionChat: trình duyệt thực hiện mọi việc

Hollama cung cấp một ứng dụng web từ một container nhỏ. Nội dung chat được lưu trong storage của trình duyệt, không phải trên server.

docker run -d --restart unless-stopped -p 127.0.0.1:4173:4173 --name hollama ghcr.io/fmaclen/hollama:latest

Phiên bản lệnh trong README dùng --rm. Tùy chọn này xóa container khi container dừng, nên giao diện không khởi động lại sau reboot. Khi đặt sau reverse proxy, hãy thêm -e VITE_ALLOWED_HOSTS='chat.example.com', vì image chỉ cho phép host localhost và trả về lỗi blocked-host khi request dùng hostname khác, thay vì mở ứng dụng.

OrionChat đi xa hơn và hoàn toàn không có server component. Clone repository rồi dùng web server hiện có để serve thư mục đó, hoặc mở index.html trực tiếp từ disk. API key được lưu trong localStorage của trình duyệt, lịch sử chat vẫn nằm trong trình duyệt, và app sẽ xóa các chat cũ nhất khi số lượng vượt quá 512.

Cả hai project đều không có login, vì không có server để kiểm tra login. Trên laptop, điều này không vấn đề. Trên VPS, điều đó có nghĩa là không được publish page trên 0.0.0.0. Đồng thời còn có một điểm dễ bỏ sót: chính trình duyệt gọi model, không phải server.

Điểm này quyết định nơi có thể sử dụng hai project. Trình duyệt phải truy cập trực tiếp vào Ollama, nên Ollama phải listen trên địa chỉ rộng hơn loopback, và Ollama không có bất kỳ cơ chế authentication nào. Từ đó có 2 quy tắc của trình duyệt. Page được serve qua HTTPS không thể gọi endpoint HTTP thuần, và console sẽ in Mixed Content: The page at 'https://chat.example.com/' was loaded over HTTPS, but requested an insecure resource 'http://203.0.113.10:11434/api/tags'. This request has been blocked.. Request đến origin khác sẽ bị từ chối với has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource cho đến khi bạn cho phép origin đó.

Cách được Ollama documentation hướng dẫn để thay đổi một trong hai setting là dùng systemd override.

sudo systemctl edit ollama.service
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=https://chat.example.com"
sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -lntp | grep 11434

ss giờ phải in 0.0.0.0:11434 thay vì 127.0.0.1:11434 như trước. Chỉ thực hiện thay đổi này khi firewall hoặc proxy có authentication đã kiểm soát những ai có thể truy cập port, vì port 11434 mở đồng nghĩa với một model server mở, và các scanner tự động sẽ nhanh chóng quét thấy port public mới. SSH tunnel bên dưới loại bỏ hoàn toàn vấn đề này: khi đó page chạy trên origin localhost, origin này được Ollama cho phép mặc định, và port không bao giờ rời khỏi máy.

Mỗi ứng dụng có thể dùng endpoint Ollama hoặc vLLM từ xa không

Open WebUI hỗ trợ, và kết nối được thực hiện ở phía server. OLLAMA_BASE_URL=http://model-host:11434 trỏ ứng dụng đến Ollama. Với vLLM hoặc bất kỳ server tương thích với OpenAI nào khác, đặt OPENAI_API_BASE_URL=http://model-host:8000/v1 với OPENAI_API_KEY không rỗng, đồng thời giữ hậu tố /v1 vì hậu tố này bắt buộc. OPENAI_API_BASE_URLS chấp nhận nhiều backend, phân tách bằng dấu chấm phẩy.

LibreChat hỗ trợ thông qua baseURL của custom endpoint được hiển thị ở trên. Request đó cũng rời khỏi server, nên không áp dụng quy tắc của browser.

Hollama và OrionChat có thể trỏ đến bất kỳ endpoint nào bạn nhập trong phần cài đặt, nhưng request rời khỏi browser. Mọi nội dung trong phần trên đều áp dụng cho chúng và không áp dụng cho ứng dụng nào khác ở đây.

Tách interface khỏi model là lợi ích thiết thực nhất của remote endpoint. Đặt interface trên một máy nhỏ và model ở nơi có đủ memory. Đây cũng là lúc quyết định Ollama hay vLLM nên xử lý các request, vì hai công cụ này hoạt động rất khác khi nhiều người dùng model cùng lúc. Nếu model server chưa tồn tại, trước tiên hãy bắt đầu bằng cách chạy Ollama trên một VPS, còn trên máy chỉ có CPU, hãy đọc cách Ollama so sánh với llama.cpp trước khi chọn runner.

Không bao giờ công khai chat UI không có đăng nhập trên 0.0.0.0

Trang hướng dẫn hardening của Open WebUI nói rằng dự án này “được xây dựng cho các mạng riêng, đáng tin cậy, tương tự những hạ tầng tự host khác như database, container registry và CI server”, đồng thời yêu cầu bạn đặt nó phía sau VPN hoặc reverse proxy có authentication. Một dự án hoàn toàn không có đăng nhập ít nhất cũng phải được xử lý như vậy.

Hãy kiểm tra những gì đang listening trước khi tin tưởng bất kỳ thành phần nào.

sudo ss -lntp | grep -E ':(3000|3080|4173|11434)'

Dòng có nội dung 127.0.0.1:3000 là kết quả bạn cần. Dòng có nội dung 0.0.0.0:3000 nghĩa là chat interface của bạn đang nằm trên public Internet. Từ chính máy của bạn, việc curl -sI http://YOUR.VPS.IP:3000 trả lời HTTP/1.1 200 OK cũng nói rõ điều đó hơn.

Tắt login của Open WebUI bằng WEBUI_AUTH=False chỉ phù hợp với máy single-user mà không ai khác có thể truy cập. Tùy chọn này cũng không áp dụng cho installation đã có account; hệ thống sẽ hiển thị thông báo You can't turn off authentication because there are existing users.

Mẫu một: bind vào loopback và truy cập qua SSH. Publish mọi port trên 127.0.0.1, sau đó forward port cần dùng: ssh -N -L 3000:127.0.0.1:3000 you@vps.example.com, rồi mở http://localhost:3000 trên laptop của bạn. Không có port nào được publish nên không có port nào để scan. Với Hollama hoặc OrionChat, hãy forward model port trong cùng command bằng -L 11434:127.0.0.1:11434 và để Ollama trên loopback. Mẫu này chỉ an toàn khi SSH được cấu hình tốt, vì vậy hãy kết hợp với SSH chỉ dùng key và sshd được harden.

Mẫu hai: dùng reverse proxy để authentication trước khi request đến app. Giữ app trên loopback, để proxy quản lý port 443 và đặt single sign-on ở phía trước. Traefik điều khiển bằng label của Docker Compose kết hợp với Authentik làm identity provider sẽ cung cấp cho mọi app trên máy một lần đăng nhập và một certificate. Khi chạy Open WebUI phía sau TLS (transport layer security), hãy đặt WEBUI_SESSION_COOKIE_SECURE=trueWEBUI_SESSION_COOKIE_SAME_SITE=strict. Đồng thời rút ngắn JWT_EXPIRES_IN so với giá trị mặc định 4 tuần, vì tài liệu Open WebUI nói rằng khi không có Redis, thao tác sign-out không invalidate token: token vẫn dùng được cho đến khi tự hết hạn.

Mẫu hai không bảo vệ được các project chỉ chạy trên browser. Proxy đặt trước page không bảo vệ model endpoint, còn request fetch từ page đến hostname khác không mang theo session cookie của bạn. Vì vậy, authentication proxy đặt trước Ollama sẽ trả về redirect đến login form và chat sẽ lỗi. Hãy route model endpoint dưới cùng hostname với page, hoặc dùng mẫu một.

Nên chọn cái nào

Nếu có người khác ngoài bạn sử dụng, hãy chạy Open WebUI. Công cụ này có tài khoản người dùng thực, người dùng mới sẽ vào hàng đợi chờ phê duyệt, và đội ngũ duy trì có tài liệu hướng dẫn hardening để bạn làm theo. Nếu cần LDAP hoặc admin panel, hãy chạy LibreChat, đồng thời xác nhận bằng docker stats rằng 6 service của nó cùng model bạn dùng vẫn phù hợp với tài nguyên trước khi phụ thuộc vào nó. Nếu chỉ có một người dùng trên một máy nhỏ, nơi model đã chiếm phần lớn RAM, hãy cung cấp Hollama hoặc OrionChat qua SSH tunnel và để trình duyệt lưu state. Lựa chọn sai trên VPS là public bất kỳ công cụ nào trong số này trên 0.0.0.0 mà không có login ở phía trước.

FAQ

Có an toàn không nếu expose Open WebUI trực tiếp trên public IP?

Trang hardening của Open WebUI mô tả đây là phần mềm dành cho private network và trusted network, tương tự database hoặc CI server. Open WebUI có hệ thống account thực sự. Account đầu tiên trở thành administrator, còn các account tạo sau vẫn ở trạng thái pending cho đến khi được phê duyệt. Vì vậy, nó an toàn hơn nhiều so với UI không có login. Tuy nhiên, vẫn nên đặt Open WebUI sau reverse proxy có TLS và, nếu có thể, dùng single sign-on. Publish container port dưới dạng 127.0.0.1:3000:8080 để các rule iptables của Docker không tự mở port này ra Internet.

Alternative nào của Open WebUI dùng ít RAM nhất trên VPS?

Các alternative chạy trên browser, gồm Hollama và OrionChat, dùng ít RAM nhất vì application chạy trên client. Server chỉ gửi static file. OrionChat thậm chí không cần application container. Open WebUI giữ một tiến trình Python, một database và, theo mặc định, một local embedding model trong memory. Tài liệu ghi nhận riêng embedding model có thể dùng khoảng 500 MB cho mỗi worker. Hãy kiểm tra con số trên chính server của bạn bằng docker stats --no-stream, vì mức dùng RAM thay đổi theo các feature được bật.

Các chat UI này có dùng được Ollama server trên host khác không?

Open WebUI và LibreChat dùng được. Server của chúng tạo kết nối, nên không bị áp dụng rule của browser. Đặt OLLAMA_BASE_URL cho Open WebUI, hoặc đặt baseURL trong custom endpoint của LibreChat. Với vLLM hoặc server tương thích OpenAI khác, dùng OPENAI_API_BASE_URL kèm suffix /v1 và một API key không rỗng. Hollama và OrionChat cũng có thể trỏ đến bất kỳ địa chỉ nào, nhưng request được gửi từ browser. Vì vậy, browser của bạn cũng phải truy cập được endpoint đó.

Vì sao chat UI trên browser không kết nối được đến Ollama?

Gần như mọi trường hợp đều do 2 nguyên nhân. Theo mặc định, Ollama bind vào 127.0.0.1:11434. Vì vậy, browser trên máy khác không thể kết nối cho đến khi OLLAMA_HOST được thay đổi. Ollama cũng chỉ chấp nhận cross-origin request từ localhost. Do đó, page được serve từ domain của bạn sẽ bị từ chối với lỗi No 'Access-Control-Allow-Origin' header is present on the requested resource cho đến khi origin đó được thêm vào OLLAMA_ORIGINS. Nếu page dùng HTTPS nhưng endpoint dùng HTTP, browser sẽ block request vì mixed content trước khi Ollama nhận được request. Đặt cả 2 biến trong một override systemctl edit ollama.service, hoặc forward port qua SSH để giải quyết vấn đề này.