LibreChat — alternativa Open WebUI za lokalne modele
U tekstu o Open WebUI postavljen je veb sloj iznad Ollame. Radi dobro i za većinu postavki je i dalje prvi izbor — ali nije jedini, i za pojedine firme nije ni najsrećniji.
LibreChat je najozbiljnija alternativa. Ovaj tekst objašnjava po čemu se razlikuje, kada ima smisla preći i kako se postavlja uz lokalni model.
Pitanje licence, bez zabluda
Prvo da se raščisti jedna stvar koja se pogrešno prepričava.
Open WebUI je besplatan i za velike firme. Nema plaćanja po korisniku, nema pretplate, nema ograničenja broja naloga. Od verzije 0.6.6 postoji jedna klauzula: u postavkama sa preko pedeset korisnika u tridesetodnevnom periodu ne smeš da ukloniš ili zameniš njihovo brendiranje — ime, logo, vizuelne oznake. Ispod tog praga i to slobodno menjaš.
Praktično, to znači sledeće:
| Situacija | Open WebUI |
|---|---|
| Interna upotreba, bilo koliko korisnika | Besplatno |
| Do 50 korisnika, uz svoj logo | Besplatno |
| Preko 50 korisnika, uz svoj logo | Traži licencu |
| Ugradnja u sopstveni proizvod | Traži licencu |
Ostaje jedna stvarna posledica: ta licenca nije OSI-odobrena. Firme koje imaju politiku da se koristi isključivo softver sa priznatih otvorenih licenci tu naiđu na zid, bez obzira na to što ništa ne plaćaju.
LibreChat je pod MIT licencom, bez ijedne klauzule. Ako te pravna služba pita, to je razlika koja ti rešava razgovor.
Po čemu se razlikuju
| Open WebUI | LibreChat | |
|---|---|---|
| Licenca | Sopstvena, uz zaštitu brenda | MIT |
| Baza | SQLite ili PostgreSQL | MongoDB, obavezno |
| Broj kontejnera | Jedan | Četiri do pet |
| Podešavanje | Kroz interfejs | Kroz librechat.yaml |
| Više provajdera odjednom | Da | Da, sa boljim prebacivanjem |
| RAG | Ugrađen, jednostavniji | Zaseban servis, pgvector |
| Pretraga razgovora | Osnovna | Meilisearch |
| Prijava kroz SSO | Da | Da, sa više gotovih provajdera |
| Podrazumevani port | 8080 u kontejneru | 3080 |
Razlika u broju kontejnera nije sitnica. Open WebUI je jedan proces i jedan fajl baze; LibreChat je mali stack. To donosi mogućnosti, ali i više toga što treba nadgledati i za šta treba praviti kopije.
Kada preći
- Politika firme traži OSI-odobrenu licencu
- Radiš sa više provajdera uporedo i često prebacuješ između njih
- Treba ti prijava kroz postojeći identitetski sistem
- Podešavanje mora da stoji u fajlu pod verzijom, ne u bazi
Kada ostati na Open WebUI
- Jedan model, nekoliko korisnika
- Hoćeš najmanje delova koje treba održavati
- Ugrađeni RAG ti je dovoljan
- Već radi i nema stvarnog razloga za promenu
Instalacija
Za razliku od Open WebUI, ovde se kreće od repozitorijuma jer su compose fajlovi deo projekta:
$ cd /opt $ sudo git clone https://github.com/danny-avila/LibreChat.git $ cd LibreChat $ sudo cp .env.example .env
Podrazumevani .env radi odmah, ali dve stvari promeni pre prvog pokretanja:
$ sudo nano .env
# Nasumične vrednosti, obavezno promeniti CREDS_KEY=32 bajta u heksadecimalnom obliku CREDS_IV=16 bajtova u heksadecimalnom obliku JWT_SECRET=nasumičan niz JWT_REFRESH_SECRET=nasumičan niz # Registracija ALLOW_REGISTRATION=true ALLOW_SOCIAL_LOGIN=false
Vrednosti se prave lako:
$ openssl rand -hex 32 # CREDS_KEY $ openssl rand -hex 16 # CREDS_IV $ openssl rand -hex 32 # JWT_SECRET
Ove ključeve obavezno promeni. Njima se šifruju korisnički API ključevi u bazi; podrazumevane vrednosti iz primera zna svako ko je otvorio repozitorijum.
$ sudo docker compose up -d $ sudo docker compose ps
Diže se pet kontejnera: api, mongodb, meilisearch, vectordb i rag_api. Prvo podizanje traje nekoliko minuta zbog preuzimanja slika.
$ sudo docker compose logs -f api
Otvori http://localhost:3080 — port se razlikuje od Open WebUI, pa mogu da rade uporedo dok porediš.
Prvi napravljen nalog je administratorski. Napravi ga odmah, pre nego što bilo šta izložiš, i onda zatvori registraciju:
ALLOW_REGISTRATION=false
$ sudo docker compose down && sudo docker compose up -d
Povezivanje sa Ollamom
Ovo je deo koji se radi u fajlu, ne u interfejsu. Treba ti dva fajla.
Kačenje konfiguracije
$ sudo cp docker-compose.override.yml.example docker-compose.override.yml $ sudo nano docker-compose.override.yml
services:
api:
volumes:
- type: bind
source: ./librechat.yaml
target: /app/librechat.yaml
ports:
- "127.0.0.1:3080:3080"
extra_hosts:
- "host.docker.internal:host-gateway"
Vezivanje porta za 127.0.0.1 je isto pravilo kao svuda u serijalu — napolju stoji proxy, ne servis.
Definisanje modela
$ sudo nano librechat.yaml
version: 1.3.13
cache: true
endpoints:
custom:
- name: 'Ollama'
apiKey: 'ollama'
baseURL: 'http://host.docker.internal:11434/v1/'
models:
default: ['qwen3:27b-q4_K_M']
fetch: true
titleConvo: true
titleModel: 'current_model'
modelDisplayLabel: 'Lokalni model'
$ sudo docker compose down && sudo docker compose up -d
Tri stvari koje se ovde najčešće pogreše.
Kosa crta na kraju baseURL. Adresa mora da se završi sa /v1/. Bez kose crte pojedine putanje se sastavljaju pogrešno i dobijaš 404 bez jasnog objašnjenja.
Ključ mora postojati. Ollama ga ignoriše, ali LibreChat odbija konfiguraciju bez njega — otud doslovno ollama kao vrednost. Ako si postavio ključeve po tekstu o zaštiti API-ja, ovde ide pravi.
Adresa zavisi od toga gde Ollama radi.
| Gde je Ollama | baseURL |
|---|---|
| Na domaćinu, kao systemd servis | http://host.docker.internal:11434/v1/ |
| U kontejneru, ista mreža | http://ollama:11434/v1/ |
| Na drugom serveru | https://ai.primer.rs/api/v1/ |
Vrednost fetch: true znači da LibreChat sam povlači spisak modela iz Ollame — ne moraš ih nabrajati ručno. Ako to zakaže, spisak u default ostaje kao rezerva.
Uz vLLM
- name: 'vLLM'
apiKey: '${VLLM_API_KEY}'
baseURL: 'http://host.docker.internal:8000/v1/'
models:
default: ['qwen3']
fetch: true
titleConvo: true
titleModel: 'qwen3'
Ključ ide u .env, ne u YAML:
VLLM_API_KEY=tajni-kljuc-ovde
Zapis ${IME} u konfiguraciji čita vrednost iz .env. To je razlog zbog kog librechat.yaml može da ide u git, a .env ne.
Provera
$ sudo docker compose logs api | grep -i 'custom endpoint\|error'
LibreChat prekida rad ako je konfiguracija neispravna, pa se greška vidi odmah po podizanju. Najčešći uzrok je uvlačenje u YAML-u — proveri pre nego što tražiš dalje:
$ python3 -c "import yaml,sys; yaml.safe_load(open('librechat.yaml'))" && echo OK
Ako se sve podiglo, u interfejsu se u padajućem meniju pojavljuje „Lokalni model". Postavi jedno pitanje i uporedo prati karticu:
$ ollama ps
Podešavanja koja vrede
$ sudo nano .env
# Adresa, obavezno tačna zbog CORS-a DOMAIN_CLIENT=https://chat.primer.rs DOMAIN_SERVER=https://chat.primer.rs # Registracija zatvorena posle prvog naloga ALLOW_REGISTRATION=false ALLOW_EMAIL_LOGIN=true # Ograničenja LIMIT_CONCURRENT_MESSAGES=true CONCURRENT_MESSAGE_MAX=2 LIMIT_MESSAGE_IP=true MESSAGE_IP_MAX=40 MESSAGE_IP_WINDOW=1 # Veličina priloga FILE_UPLOAD_SIZE_LIMIT=50
Vrednosti DOMAIN_* moraju odgovarati stvarnoj adresi preko koje pristupaš. Ako se razlikuju, interfejs se učita ali prijava ne radi — greška koja izgleda kao pokvarena baza, a nije.
Ograničenja su ovde korisnija nego kod Open WebUI, jer ih LibreChat sprovodi sam. To ne zamenjuje ograničenja na proxy-ju, ali je dodatni sloj bliži korisniku.
Reverse proxy
Ista pravila kao za Open WebUI, samo drugi port:
server {
listen 443 ssl;
http2 on;
server_name chat.primer.rs;
ssl_certificate /etc/letsencrypt/live/chat.primer.rs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.primer.rs/privkey.pem;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:3080;
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;
proxy_read_timeout 600s;
}
}
Bez proxy_buffering off nema postepenog ispisa; bez WebSocket zaglavlja poruke ne stižu. Detaljno u tekstu o proxy-ju.
Rezervne kopije
Ovde je najveća praktična razlika u odnosu na Open WebUI. Nema jednog SQLite fajla — podaci su u MongoDB, a prilozi na disku.
$ sudo tee /opt/LibreChat/kopija.sh > /dev/null <<'SKRIPTA'
#!/bin/bash
set -euo pipefail
cd /opt/LibreChat
ODREDISTE=/backup/librechat
DATUM=$(date +%F)
mkdir -p "$ODREDISTE"
docker compose exec -T mongodb mongodump --archive --gzip \
> "$ODREDISTE/mongo-$DATUM.gz"
tar -czf "$ODREDISTE/prilozi-$DATUM.tar.gz" ./uploads ./images 2>/dev/null || true
cp .env "$ODREDISTE/env-$DATUM"
cp librechat.yaml "$ODREDISTE/yaml-$DATUM" 2>/dev/null || true
find "$ODREDISTE" -mtime +30 -delete
SKRIPTA
$ sudo chmod 755 /opt/LibreChat/kopija.sh
0 4 * * * /opt/LibreChat/kopija.sh
Vraćanje:
$ docker compose exec -T mongodb mongorestore --archive --gzip --drop \
< /backup/librechat/mongo-2026-08-24.gz
Fajl .env mora u kopiju. Bez ključeva CREDS_KEY i CREDS_IV šifrovani sadržaj u vraćenoj bazi je neupotrebljiv. Kopiju drži zaštićenu, jer sadrži sve tajne.
Zakazivanje pokriva tekst o cronu.
Ažuriranje
$ cd /opt/LibreChat $ sudo ./kopija.sh $ sudo docker compose down $ sudo git pull $ sudo docker compose pull $ sudo docker compose up -d
Korak sa git pull je obavezan, za razliku od Open WebUI — compose fajlovi i primeri konfiguracije dolaze iz repozitorijuma i menjaju se uz nove verzije.
Ako si menjao docker-compose.yml, git pull će se sudariti sa tvojim izmenama. Zato izmene idu isključivo u docker-compose.override.yml, koji projekat ne dira.
Šta još dobijaš
Nekoliko stvari koje su razrađenije nego u Open WebUI.
Poređenje modela. Isto pitanje kroz dva modela uporedo, u istom prozoru — korisno kad biraš šta da hostuješ, uz merenja iz teksta o benchmarku.
Agenti i MCP. Podrška za protokol iz teksta o MCP-u je ugrađena, sa podešavanjem serverâ u istom YAML fajlu. Ista upozorenja odatle važe neizmenjeno — alati koji samo čitaju, spisak dozvoljenih vrednosti, bez izvršavanja bez potvrde.
Pretraga kroz istoriju. Meilisearch pretražuje sve razgovore, što na godinu dana upotrebe postane primetna razlika.
Podešavanje pod verzijom. Ceo librechat.yaml ide u git. Kod Open WebUI podešavanja žive u bazi, pa se ne mogu pregledati kao izmena u kodu.
Šta je slabije
Više delova. Pet kontejnera umesto jednog znači pet stvari koje mogu da otkažu i koje treba nadgledati po tekstu o monitoringu.
Teže na resursima. MongoDB i Meilisearch traže oko gigabajta memorije pre nego što iko išta upita.
RAG je zaseban servis. Moćniji, ali i još jedna stvar u lancu. Ako ti treba samo pitanje nad dokumentom, ugrađeni RAG u Open WebUI je jednostavniji, a za ozbiljnije sopstveno rešenje ionako gradiš sam.
Podešavanje kroz fajl. Prednost za tebe, prepreka za kolegu koji bi hteo sam da doda model.
Praktični scenariji
Scenario 1: model se ne pojavljuje u meniju
$ sudo docker compose logs api | tail -50
Redom: da li je librechat.yaml zakačen kroz override fajl, da li je YAML ispravan, da li adresa Ollame odgovara mestu gde ona radi.
Scenario 2: kontejner se odmah gasi
Neispravna konfiguracija — LibreChat namerno prekida rad umesto da radi sa polovičnim podešavanjima. Greška je u logu api.
Scenario 3: interfejs radi, prijava ne
Vrednosti DOMAIN_CLIENT i DOMAIN_SERVER ne odgovaraju adresi preko koje pristupaš.
Scenario 4: izmena u .env nema efekta
$ sudo docker compose down && sudo docker compose up -d
Compose čita .env samo pri pokretanju kontejnera. Obično restart ga ne osvežava.
Scenario 5: 404 na svaki zahtev ka modelu
Nedostaje kosa crta na kraju baseURL. Mora biti /v1/.
Scenario 6: git pull se sudara sa izmenama
Menjao si fajlove koji pripadaju projektu. Vrati ih u prvobitno stanje i sve svoje prebaci u docker-compose.override.yml.
Kratka referenca
- Open WebUI je besplatan i preko 50 korisnika — licenca se tiče samo brendiranja
- LibreChat je MIT — bez ijedne klauzule
git clone+cp .env.example .env+docker compose up -dopenssl rand -hex 32— obavezno promeniCREDS_KEYiJWT_SECRET- Port 3080, ne 3000
- Prvi nalog je administratorski; odmah zatim
ALLOW_REGISTRATION=false docker-compose.override.yml— jedino mesto za tvoje izmenelibrechat.yaml— definicija modela; ide u gitbaseURLmora se završiti sa/v1/apiKey: 'ollama'— mora postojati iako se ne proveravafetch: true— spisak modela se povlači sam${IME}u YAML-u čita vrednost iz.envDOMAIN_CLIENTiDOMAIN_SERVER— netačni znače da prijava ne radimongodump --archive --gzip— kopija; uz nju obavezno.env- Posle izmene
.envidedownpaup, nerestart
Vežba
- Postavi LibreChat na port 3080, uporedo sa postojećim Open WebUI, i napravi administratorski nalog.
- Poveži ga sa lokalnom Ollamom i potvrdi da se spisak modela povlači sam.
- Namerno izostavi kosu crtu na kraju
baseURLi pogledaj kako greška izgleda. - Dodaj drugi endpoint i uporedi isti upit kroz oba modela.
- Napravi kopiju baze, obriši kontejner sa podacima, pa je vrati.
- Postavi oba interfejsa iza proxy-ja na zasebnim imenima i odluči koji ostaje.
Povezano:
- AI na Linux serveru — pregled celog serijala
- Open WebUI — druga strana ovog poređenja
- Ollama: instalacija na Linux serveru — servis ispod interfejsa
- Nginx reverse proxy i HTTPS — izlaganje prema mreži
- Docker Compose — više kontejnera odjednom
Comments
Post a Comment