Open WebUI hay lựa chọn nào tốt cho VPS?
So sánh Open WebUI, LibreChat, Hollama và OrionChat trên VPS public IP: RAM còn lại cho model, login, Ollama từ xa và công sức bảo trì.
Ứng dụng thay thế Open WebUI nào phù hợp với VPS
Các lựa chọn thay thế 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 listening trên địa chỉ public. VPS thay đổi cả hai yếu tố này, nên thứ hạng 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ì ứng dụng này ships tài khoản người dùng thực và admin panel. Các dự án nhẹ hơn có lợi thế khi giao diện phải cạnh tranh với model cho phần RAM cuối cùng. Đổi lại, 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 dự án, được đọc vào tháng 8 năm 2026. Bốn tiêu chí này chỉ trở nên quan trọng khi máy chủ có thể truy cập từ Internet.
Chỉ có 4 tiêu chí thực sự quan trọng khi dùng public IP
- Bộ nhớ dùng cùng với model. Model server là tiến trình ngốn tài nguyên nhất trên máy. Mỗi megabyte mà interface sử dụng 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à ứng dụng duy nhất chạy trên laptop của bạn nên không có chức năng login.
- Inference từ xa. UI chỉ có thể kết nối đến
127.0.0.1:11434sẽ 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 cùng file SQLite khác hoàn toàn với 6 container có MongoDB và vector database chạy phía sau.
Model chừa lại 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 nhất. Kích thước download được công bố chỉ cho biết mức tối thiểu, vì weights phải nằm trong RAM khi model tạo câu trả lời. Mức sử dụng RAM thực tế cao hơn kích thước download sau khi context cache được cấp phát.
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 mà các trang thư viện Ollama hiển thị vào tháng 8 năm 2026. Chúng là kích thước được công bố, không phải kết quả đo. Trên một VPS 4 GB, qwen3:4b ở mức 2.5 GB chỉ chừa lại 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 RAM khi cuộc trò chuyện dài lên. Vì vậy, num_ctx bạn đặt là một quyết định về bộ nhớ cũng như chất lượng. qwen3:8b ở mức 5.2 GB hoàn toàn không chạy được trên máy đó. Đây là tình huống mà các bài tổng hợp về laptop thường không đề cập. Một chat interface chỉ chiếm vài trăm megabyte cũng có thể quyết định model có chạy được hay không. Nếu bạn dự định chọn máy cho model lớn hơn đáng kể so với các tag này, phép tính cho model 27B trên VPS chỉ dùng CPU cho thấy interface nhanh chóng không còn là yếu tố quyết định.
Hãy đo thực tế thay vì tin bất kỳ con số nào trong bài tổng hợp, kể cả con số ở đây. Chạy docker stats --no-stream sau khi hệ thống đã được sử dụng thực tế 1 giờ, không phải 1 phút sau khi container khởi động, vì phần RAM cần quan tâm chỉ được cấp phát khi sử dụng lần đầu. Ollama cũng giải phóng weights sau 5 phút không hoạt động. Vì vậy, kết quả đo giữa hai cuộc trò chuyện sẽ thấp hơn mức đỉnh. Tin nhắn tiếp theo sẽ phải nạp lại toàn bộ model, trừ khi bạn giữ model trong RAM bằng keep_alive.
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:mainCommand trong README của project publish -p 3000:8080, cổng này lắng nghe trên mọi interface. Prefix 127.0.0.1: giữ cổng này 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 rule iptables và port đã 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 account đầu tiên. Account đó trở thành administrator. Các lần đăng ký sau được tạo với role pending, là giá trị mặc định được tài liệu hóa của DEFAULT_USER_ROLE, nên người lạ truy cập được trang vẫn không thể dùng model của bạn cho đến khi admin phê duyệt.
Open WebUI dùng nhiều memory hơn các project bên dưới vì có nhiều chức năng hơn, và trang performance của project 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, theo tài liệu là khoảng 500 MB cho mỗi worker process. Đặt RAG_EMBEDDING_ENGINE=ollama để chuyển công việc đó cho model server bạn đã chạy sẵn. AUDIO_STT_ENGINE=webapi giúp tránh 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, nên trên máy cấu hình thấp hãy đặt DATABASE_POOL_SIZE=8 và DATABASE_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 user, với một stack phía sau
git clone https://github.com/danny-avila/LibreChat.git
cd LibreChat
cp .env.example .env
docker compose up -dGiao diện lắng nghe trên cổng 3080. LibreChat phù hợp khi bạn cần một hệ thống identity thay vì chỉ một ô đăng nhập: tài liệu của dự án có hướng dẫn đă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.
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, và trên máy 4 GB thì đó là phần memory lẽ ra dành cho model.
Nâng cấp là một thao tác git, và đây là phần nhiều người làm sai.
docker compose down
git pull
docker compose pull
docker compose up -dgit pull sẽ dừng với conflict nếu bạn đã sửa docker-compose.yml đang được track, khiến quá trình nâng cấp chỉ hoàn tất 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à giữ secret trong .env. Cả hai file đều không được track, nên git pull sẽ không động đến chúng.
Trỏ LibreChat đến model server của bạn bằng 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 tồn tại dù Ollama bỏ qua giá trị của nó, 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 đó, vì vậy hãy dùng host.docker.internal thay thế.
Hollama và OrionChat: trình duyệt xử lý mọi việc
Hollama cung cấp một ứng dụng web từ một container nhỏ. Nội dung chat nằm trong storage của trình duyệt, không nằm trên server.
docker run -d --restart unless-stopped -p 127.0.0.1:4173:4173 --name hollama ghcr.io/fmaclen/hollama:latestPhiê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 interface không tự hoạt động lại sau reboot. Khi chạy sau reverse proxy, hãy thêm -e VITE_ALLOWED_HOSTS='chat.example.com', vì image chỉ cho phép host localhost và sẽ trả về lỗi blocked-host thay vì ứng dụng nếu request dùng hostname khác.
OrionChat còn tối giản hơn và hoàn toàn không có thành phần server. 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 có vấn đề. Trên VPS, điều đó có nghĩa là không được publish page tại 0.0.0.0. Đồng thời, còn một điểm dễ bỏ sót: trình duyệt gọi model, không phải server.
Điểm này quyết định nơi có thể dùng hai project này. 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, trong khi Ollama không có bất kỳ cơ chế authentication nào. Từ đó có 2 quy tắc của trình duyệt. Một page chạy qua HTTPS không thể gọi endpoint HTTP thuần. 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 bằng 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 document để thay đổi một trong hai setting này 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 11434ss hiện phải in 0.0.0.0:11434 thay vì 127.0.0.1:11434 như trước. Chỉ thay đổi setting này khi firewall hoặc proxy có authentication đã kiểm soát người được phép truy cập port, vì port 11434 mở đồng nghĩa với một model server mở và các mass scanner thường nhanh chóng phát hiện port public mới. SSH tunnel bên dưới tránh hoàn toàn vấn đề này: khi đó page chạy trên origin localhost, origin này mặc định được Ollama cho phép, 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 có thể dùng, 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 nào tương thích với OpenAI, đặt OPENAI_API_BASE_URL=http://model-host:8000/v1 cùng một OPENAI_API_KEY không rỗng, và 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, ngăn cách bằng dấu chấm phẩy.
LibreChat có thể dùng thông qua baseURL của custom endpoint được nêu ở trên. Request đó cũng rời khỏi server, nên không áp dụng quy tắc của browser. Cùng base URL và placeholder key đó cũng hoạt động bên ngoài cửa sổ chat, nên chỉ cần vậy là có thể trỏ coding agent đến model bạn đã host.
Hollama và OrionChat có thể trỏ đến bất kỳ endpoint nào bạn nhập trong phần settings, 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 thành phần nào khác ở đây.
Tách interface khỏi model là lợi ích hữu ích nhất mà remote endpoint mang lại. Đặt interface trên một máy nhỏ và đặt model ở nơi có đủ memory. Đây cũng là lúc quyết định nên dùng Ollama hay vLLM để phục vụ request, vì hai công cụ này hoạt động rất khác khi nhiều người cùng lúc gửi request đến model. Nếu model server chưa tồn tại, trước tiên hãy chạy Ollama trên một VPS, còn trên máy chỉ có CPU, hãy đọc so sánh Ollama với llama.cpp trước khi chọn runner.
Không bao giờ public chat UI không có login trên 0.0.0.0
Trang hardening của Open WebUI cho biết dự án này được “thiết kế cho các mạng riêng, đáng tin cậy, tương tự những hạ tầng self-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ó login ít nhất cũng phải được bảo vệ 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 thấy. Dòng có nội dung 0.0.0.0:3000 nghĩa là chat interface của bạn đang ở trên public Internet. Từ chính máy của bạn, việc curl -sI http://YOUR.VPS.IP:3000 trả về HTTP/1.1 200 OK cũng cho thấy điều đó theo cách trực tiếp hơn.
Tắt login của Open WebUI bằng WEBUI_AUTH=False chỉ phù hợp với máy dùng cho một người mà không ai khác có thể truy cập. Tùy chọn này cũng không áp dụng được cho installation đã có account. Khi đó, nó 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. Không có port nào được publish nên không thể bị scan. Với Hollama hoặc OrionChat, forward model port trong cùng command bằng -L 11434:127.0.0.1:11434 và để Ollama trên loopback. Mức độ an toàn của mẫu này chỉ bằng cấu hình SSH, vì vậy hãy kết hợp với SSH chỉ dùng key và sshd được harden.
Mẫu hai: reverse proxy xác thực trước khi app nhận request. Giữ app trên loopback, để proxy quản lý port 443 và đặt single sign-on ở phía trước. Traefik được điều khiển bằng label của Docker Compose kết hợp với Authentik làm identity provider cho mọi app trên máy dùng chung một login và một certificate. Khi đặt Open WebUI phía sau TLS (transport layer security), hãy đặt WEBUI_SESSION_COOKIE_SECURE=true và WEBUI_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 cho biết rằng nếu không có Redis thì 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ỉ hỗ trợ trên browser. Proxy đặt trước trang web không bảo vệ model endpoint. Một fetch từ trang đó đến hostname khác cũng không mang theo session cookie của bạn. Vì vậy, authenticating proxy đặt trước Ollama sẽ trả về redirect đến login form và chat sẽ bị lỗi. Hãy route model endpoint dưới cùng hostname với trang web, hoặc dùng mẫu một.
Chọn phương án nào
Nếu có người khác ngoài bạn sử dụng, hãy chạy Open WebUI. Ứng dụng này có account riêng, người dùng mới sẽ vào hàng đợi chờ phê duyệt, và maintainer 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 và xác nhận bằng docker stats rằng 6 service của nó cùng model của bạn thực sự phù hợp 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 phục vụ Hollama hoặc OrionChat qua SSH tunnel và để browser giữ state. Trên VPS, phương án sai là public bất kỳ ứng dụng nào trong số này trên 0.0.0.0 mà không có login ở phía trước.
FAQ
Open WebUI có an toàn khi expose trực tiếp trên public IP không?
Trang hardening của Open WebUI mô tả đây là phần mềm dành cho private network và trusted network, cùng nhóm với database hoặc CI server. Open WebUI có account thực. 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 approve. 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à dùng single sign-on nếu có thể. 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 phía sau bạn.
Open WebUI alternative nào dùng ít RAM nhất trên VPS?
Các ứng dụng 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, và OrionChat không cần application container. Open WebUI giữ một Python process, một database và mặc định là một local embedding model trong memory. Tài liệu ghi embedding model riêng có thể dùng khoảng 500 MB cho mỗi worker. Hãy xác nhận số liệu trên máy của bạn bằng docker stats --no-stream, vì mức dùng RAM thay đổi theo các feature bạn 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 connection, nên không á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 cùng suffix /v1 và một API key không rỗng. Hollama và OrionChat cũng có thể trỏ đến bất kỳ endpoint nào, nhưng request được gửi từ browser của bạn. Vì vậy, endpoint cũng phải reachable từ browser.
Vì sao browser chat UI của tôi không thể kết nối đến Ollama?
Gần như mọi trường hợp đều do một trong 2 nguyên nhân. Ollama mặc định bind vào 127.0.0.1:11434, nên 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ỉ accept cross-origin request từ localhost. Vì vậy, một page được serve từ domain của bạn sẽ bị từ chối vớ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 còn endpoint dùng HTTP, browser sẽ block request dưới dạng 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 đề.