How to Install LibreChat on Ubuntu 24.04 VPS: Self-Hosted Multi-Provider AI Chat Platform
LibreChat is an open-source, feature-complete ChatGPT clone that you can run on your own server. Unlike the official ChatGPT web app, LibreChat connects to every major LLM provider (OpenAI, Anthropic Claude, Google Gemini, Mistral, Groq, AWS Bedrock, Azure, Ollama, and dozens of others) through a single unified interface. It ships with multi-user authentication, conversation history, file uploads with RAG, plugins, agents, presets, voice input, and image generation -- all without sending your chats to a third-party SaaS.
This tutorial walks you through a production deployment of LibreChat on Ubuntu 24.04, from provisioning the VPS to enabling TLS in front of a hardened Docker Compose stack. By the end you will have a private ChatGPT-style workspace available at https://chat.yourdomain.com, backed by MongoDB for history, Meilisearch for full-text search, and a RAG service for document Q&A.
Running Ollama locally? You can wire your Ollama endpoint into LibreChat as another provider in Step 7. See our companion guide: How to install Ollama on Ubuntu 24.04.
Table of Contents
.env Filelibrechat.yaml (Endpoints, Plugins, Agents)What is LibreChat?
LibreChat is an MIT-licensed AI chat platform originally forked from the early OpenAI "ChatGPT Clone" project and now maintained by a large open-source community. It aims to be the single chat UI for every model you might want to use, combining a polished React frontend with a Node.js/Express backend, MongoDB for persistence, Meilisearch for conversation search, and an optional Python rag_api service for retrieval-augmented document chat.
Feature-wise LibreChat is unusually comprehensive for a self-hosted tool. It supports multi-user accounts with email/password registration, OAuth (Google, GitHub, Discord, Facebook, Apple), LDAP, and OpenID Connect for enterprise SSO. Every user gets isolated conversations, and admins can configure per-user rate limits, message caps, and model visibility. The interface supports branching conversations, where you can fork a thread at any message and explore alternative replies side by side -- something the official ChatGPT UI does not do.
On the model side, LibreChat speaks natively to OpenAI (GPT-4o, GPT-4, GPT-3.5, o1-preview, o1-mini), Anthropic (Claude 3.5 Sonnet, Claude 3 Opus, Haiku), Google (Gemini 1.5 Pro, Flash, PaLM 2), Mistral, Groq, Perplexity, OpenRouter, AWS Bedrock, Azure OpenAI, and any OpenAI-compatible endpoint -- which means Ollama, vLLM, LocalAI, and LM Studio all plug in as custom endpoints. You can switch models mid-conversation, compare responses with "multi-response" mode, and define presets (saved system prompts + model + parameters) for one-click reuse.
Beyond plain chat, LibreChat includes plugins (function-calling tools like web browsing, DALL-E, Wolfram, Google Search, Zapier), agents (a custom agent builder with tool calling, code interpreter, and memory), file uploads with RAG (drop in PDFs, DOCX, spreadsheets, or code and chat over their contents), image generation via DALL-E 3 or Stable Diffusion, voice input/output using OpenAI Whisper + TTS or ElevenLabs, and conversation export to JSON, Markdown, or screenshot. For developers, it exposes an OpenAI-compatible API of its own, so downstream apps can talk to LibreChat as if it were OpenAI.
Why Self-Host LibreChat?
Running LibreChat on your own VPS has concrete advantages over paying for ChatGPT Team, Claude Pro, or Gemini Advanced separately:
- One subscription, every model -- Use your own OpenAI, Anthropic, and Google API keys and pay only for tokens consumed. No duplicated $20/month seats across three vendors.
- Data sovereignty -- Conversations, uploaded files, and the Meilisearch index live on your server. Nothing transits a third-party app's database. For teams in regulated industries (legal, healthcare, finance), this is often the difference between "approved" and "blocked."
- Unlimited seats -- LibreChat has no per-user licensing. Invite 5 or 500 users; the cost is the same flat VPS price plus the API tokens they consume.
- Mix hosted and local models -- Use Claude 3.5 Sonnet for hard reasoning, GPT-4o for general chat, and a local Ollama-hosted Llama 3.1 for sensitive internal documents -- all in the same UI.
- No silent model changes -- Providers deprecate or silently swap models all the time. With LibreChat you pin exact model IDs in
librechat.yaml. - Audit trails and rate limits -- Admins can cap per-user spend, enforce message quotas, and export full conversation logs for compliance review.
- Branching, presets, and agents -- Power-user features that no consumer chat product exposes.
Cost Comparison vs. Commercial Chat Suites
| Scenario (10 users, moderate use) | ChatGPT Team | Claude Pro x10 | Gemini Advanced x10 | Self-Hosted LibreChat |
|---|---|---|---|---|
| Monthly subscription | $300 ($30/user) | $200 ($20/user) | $200 ($20/user) | VPS: EUR 19.99/mo |
| API token usage | Included (capped) | Included (capped) | Included (capped) | Pay-as-you-go per provider |
| Access to all providers | No (OpenAI only) | No (Anthropic only) | No (Google only) | Yes (any provider) |
| Data isolation | Shared tenant | Shared tenant | Shared tenant | Your VPS only |
| User cap | 10 seats | 10 seats | 10 seats | Unlimited |
| Typical all-in cost | ~$300 | ~$200 | ~$200 | EUR 20 + ~$30-80 tokens |
Prerequisites
Before you start you will need:
- A VPS running Ubuntu 24.04 LTS with root or sudo access.
- A registered domain with an
Arecord pointing to the server (e.g.chat.yourdomain.com). - At least 4 GB of RAM (8 GB recommended when RAG and Meilisearch are both enabled).
- At least 30 GB of disk space for Docker images, MongoDB data, uploaded files, and the Meilisearch index.
- SSH access and basic familiarity with
docker compose. - API keys for the providers you plan to use (OpenAI, Anthropic, Google are the common set).
Recommended plan: CloudCore Professional>
LibreChat's stack (MongoDB + Meilisearch + RAG API + the Node backend + the React frontend) is heavier than Open WebUI. For a smooth experience with RAG enabled and 5-15 active users we recommend the CloudCore Professional plan:>
- 6 vCPU cores
- 12 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth
- EUR 19.99/month>
If you plan to also run Ollama on the same box (Step 7), size up to 16 GB+ RAM so the 7B model has headroom alongside MongoDB and Meilisearch.
Connect to your server to begin:
ssh root@your-server-ipStep 1: Prepare the Ubuntu 24.04 VPS
Update packages and install basic tooling.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git ufw ca-certificates gnupg lsb-releaseCreate a non-root user for running the stack if you do not already have one:
sudo adduser librechat
sudo usermod -aG sudo librechatConfigure the firewall to allow SSH, HTTP, and HTTPS only:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw statusExpected output:
Status: active
To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere
Log in as the new user before continuing:
su - librechatStep 2: Install Docker and Docker Compose
LibreChat is deployed as a multi-container application using Docker Compose. If you already have Docker installed, skip ahead. Otherwise, follow the abbreviated version below -- or see our dedicated guide: How to install Docker on Ubuntu 24.04.
Add the Docker APT repository:
sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install the engine and Compose v2:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginAdd your user to the docker group so you do not need sudo for every command:
sudo usermod -aG docker $USER
newgrp dockerVerify the install:
docker --version
docker compose versionExpected output:
Docker version 27.3.1, build ce1223035a
Docker Compose version v2.29.7Step 3: Clone the LibreChat Repository
LibreChat ships an official docker-compose.yml in its main repo. Clone it into /opt/librechat (or your preferred location):
sudo mkdir -p /opt/librechat
sudo chown $USER:$USER /opt/librechat
cd /opt/librechat
git clone https://github.com/danny-avila/LibreChat.git .Expected output:
Cloning into '.'...
remote: Enumerating objects: 52341, done.
remote: Counting objects: 100% (1234/1234), done.
remote: Compressing objects: 100% (567/567), done.
Receiving objects: 100% (52341/52341), 45.67 MiB | 15.23 MiB/s, done.
Resolving deltas: 100% (34567/34567), done.Pin to the latest stable release tag (recommended for production):
git fetch --tags
git checkout v0.7.8Replace v0.7.8 with whatever is current on the releases page. Using a tag instead of main prevents a git pull from accidentally introducing breaking changes during a routine update.
Copy the example configuration files:
cp .env.example .env
cp librechat.example.yaml librechat.yaml
cp docker-compose.override.yml.example docker-compose.override.ymlStep 4: Generate Secrets and Configure the .env File
LibreChat requires four cryptographic secrets: CREDS_KEY, CREDS_IV, JWT_SECRET, and JWT_REFRESH_SECRET. These sign sessions and encrypt user-supplied API keys at rest. Generate them with openssl:
echo "CREDS_KEY=$(openssl rand -hex 32)"
echo "CREDS_IV=$(openssl rand -hex 16)"
echo "JWT_SECRET=$(openssl rand -hex 32)"
echo "JWT_REFRESH_SECRET=$(openssl rand -hex 32)"Copy the four printed lines. Now edit .env:
nano .envSet or update the following keys (leave everything else at defaults for now):
# --- App basics ---
HOST=0.0.0.0
PORT=3080
DOMAIN_CLIENT=https://chat.yourdomain.com
DOMAIN_SERVER=https://chat.yourdomain.com--- MongoDB (internal Docker network) ---
MONGO_URI=mongodb://mongodb:27017/LibreChat--- Secrets (paste the openssl output) ---
CREDS_KEY=<paste 64-char hex here>
CREDS_IV=<paste 32-char hex here>
JWT_SECRET=<paste 64-char hex here>
JWT_REFRESH_SECRET=<paste 64-char hex here>--- Registration policy ---
ALLOW_EMAIL_LOGIN=true
ALLOW_REGISTRATION=true # set to false after creating your admin
ALLOW_SOCIAL_LOGIN=false
ALLOW_SOCIAL_REGISTRATION=false--- Search ---
SEARCH=true
MEILI_NO_ANALYTICS=true
MEILI_HOST=http://meilisearch:7700
MEILI_MASTER_KEY=<generate with openssl rand -hex 32>--- Rate limiting (optional but recommended) ---
LIMIT_CONCURRENT_MESSAGES=true
CONCURRENT_MESSAGE_MAX=2
LIMIT_MESSAGE_IP=true
MESSAGE_IP_MAX=40
MESSAGE_IP_WINDOW=1--- RAG ---
RAG_API_URL=http://rag_api:8000
EMBEDDINGS_PROVIDER=openai
EMBEDDINGS_MODEL=text-embedding-3-smallImportant: Once you create your first account, come back and flip ALLOW_REGISTRATION=false to prevent anyone who discovers your URL from signing up. For multi-user deployments, keep it on but combine it with ALLOWED_REGISTRATION_DOMAINS=yourcompany.com to restrict to corporate email.
Step 5: Review the Docker Compose Stack
Open docker-compose.yml and have a look at the services that will run:
nano docker-compose.ymlThe default stack defines five services:
version: '3.8'services: # --- MongoDB: conversation history, users, presets, agents --- mongodb: image: mongo:7 container_name: chat-mongodb restart: always volumes: - ./data-node:/data/db command: mongod --noauth
# --- Meilisearch: full-text search over conversations --- meilisearch: image: getmeili/meilisearch:v1.7.3 container_name: chat-meilisearch restart: always environment: - MEILI_HOST=http://meilisearch:7700 - MEILI_NO_ANALYTICS=true - MEILI_MASTER_KEY=${MEILI_MASTER_KEY} volumes: - ./meili_data_v1.12:/meili_data
# --- RAG API: embedding + vector search for uploaded files --- rag_api: image: ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest container_name: chat-rag-api restart: always environment: - DB_HOST=vectordb - RAG_PORT=8000 - OPENAI_API_KEY=${OPENAI_API_KEY} depends_on: - vectordb
vectordb: image: ankane/pgvector:latest container_name: chat-vectordb restart: always environment: - POSTGRES_DB=mydatabase - POSTGRES_USER=myuser - POSTGRES_PASSWORD=mypassword volumes: - ./pgdata2:/var/lib/postgresql/data
# --- LibreChat API + static client --- api: image: ghcr.io/danny-avila/librechat-dev:latest container_name: LibreChat restart: always ports: - "127.0.0.1:3080:3080" env_file: - .env volumes: - ./librechat.yaml:/app/librechat.yaml - ./images:/app/client/public/images - ./uploads:/app/uploads - ./logs:/app/api/logs depends_on: - mongodb - meilisearch - rag_api
Note that the api container binds to 127.0.0.1:3080, not 0.0.0.0. This is deliberate -- Nginx will terminate TLS and reverse-proxy to this local port. Never expose port 3080 directly to the internet.
Step 6: Configure Provider API Keys
Add your LLM provider credentials to .env. You only need the ones you actually plan to use -- LibreChat gracefully hides endpoints with missing keys.
nano .envAdd the following block:
# ---------- OpenAI ---------- OPENAI_API_KEY=sk-proj-...Restrict to specific models (optional)
OPENAI_MODELS=gpt-4o,gpt-4o-mini,gpt-4-turbo,o1-miniTitle generation on a cheap model saves money
OPENAI_TITLE_MODEL=gpt-4o-mini---------- Anthropic ----------
ANTHROPIC_API_KEY=sk-ant-... ANTHROPIC_MODELS=claude-3-5-sonnet-20241022,claude-3-5-haiku-20241022,claude-3-opus-20240229---------- Google (Gemini / PaLM) ----------
GOOGLE_KEY=AIza... GOOGLE_MODELS=gemini-1.5-pro-latest,gemini-1.5-flash-latest---------- Groq, Mistral, OpenRouter (OpenAI-compatible) ----------
GROQ_API_KEY=gsk_... MISTRAL_API_KEY=... OPENROUTER_KEY=sk-or-...---------- Ollama (local, no key needed) ----------
We configure Ollama via librechat.yaml in Step 7,
but if Ollama runs on the same VPS, use:
host.docker.internal:11434
After adding the extra_hosts line in docker-compose.override.yml.
For Ollama in particular, LibreChat accesses it over HTTP, so you need to tell the LibreChat container how to reach the host. Edit docker-compose.override.yml:
services:
api:
extra_hosts:
- "host.docker.internal:host-gateway"This is the standard Docker Desktop-style escape hatch so the container can hit host.docker.internal:11434 where your Ollama service listens.
Step 7: Customise librechat.yaml (Endpoints, Plugins, Agents)
While .env holds secrets and flags, librechat.yaml is where you declare endpoints, enable features, and set user-facing policy. Open it:
nano librechat.yamlHere is a solid starter configuration that enables OpenAI, Anthropic, Google, Ollama (custom endpoint), plugins, and agents:
version: 1.2.1 cache: true--- Interface policy ---
interface: privacyPolicy: externalUrl: 'https://yourdomain.com/privacy' openNewTab: true termsOfService: externalUrl: 'https://yourdomain.com/terms' openNewTab: true endpointsMenu: true modelSelect: true parameters: true sidePanel: true presets: true agents: true prompts: true bookmarks: true multiConvo: true--- Registration restrictions ---
registration: socialLogins: ['github', 'google'] # Uncomment to restrict registration to a single corporate domain # allowedDomains: # - 'yourcompany.com'--- Rate limits ---
rateLimits: fileUploads: ipMax: 100 ipWindowInMinutes: 60 userMax: 50 userWindowInMinutes: 60 conversationsImport: ipMax: 100 ipWindowInMinutes: 60 userMax: 50 userWindowInMinutes: 60--- File-handling and RAG ---
fileConfig: endpoints: default: fileLimit: 10 fileSizeLimit: 20 # MB per file totalSizeLimit: 50 # MB per request supportedMimeTypes: - 'application/pdf' - 'text/.*' - 'application/json' - 'image/.*' - 'application/vnd.openxmlformats-officedocument.*' serverFileSizeLimit: 100 avatarSizeLimit: 2--- Custom endpoints (Ollama, Groq, etc.) ---
endpoints: custom: - name: 'Ollama (local)' apiKey: 'ollama' baseURL: 'http://host.docker.internal:11434/v1/' models: default: ['llama3.1:8b', 'mistral', 'gemma2:9b'] fetch: true titleConvo: true titleModel: 'llama3.1:8b' modelDisplayLabel: 'Ollama'
- name: 'Groq' apiKey: '${GROQ_API_KEY}' baseURL: 'https://api.groq.com/openai/v1/' models: default: ['llama-3.1-70b-versatile', 'mixtral-8x7b-32768'] fetch: false titleConvo: true titleModel: 'llama-3.1-8b-instant' modelDisplayLabel: 'Groq'
Enable Plugins
Plugins are LibreChat's function-calling tools (DALL-E, web browser, Wolfram, Stable Diffusion, Zapier, and custom OpenAPI specs). Turn them on by adding the relevant env vars in .env:
# --- Plugins ---
PLUGINS_USE_AZURE=false
PLUGIN_MODELS=gpt-4o,gpt-4o-mini,claude-3-5-sonnet-20241022Tool-specific credentials
DALLE3_API_KEY=sk-proj-... # uses OpenAI key
GOOGLE_SEARCH_API_KEY=AIza...
GOOGLE_CSE_ID=...
WOLFRAM_APP_ID=...
SERPAPI_API_KEY=...
ZAPIER_NLA_API_KEY=...Plugins appear as the "wrench" icon in the chat UI and can be toggled per-conversation.
Enable Agents
Agents are LibreChat's own agent builder -- more powerful than plugins because they persist tools, memory, and instructions. They are enabled under interface.agents: true (set above) and require that at least one compatible endpoint (OpenAI, Anthropic, or any endpoint supporting function calling) is configured.
Step 8: Launch the Stack
From /opt/librechat, pull images and start all services:
cd /opt/librechat
docker compose pull
docker compose up -dExpected output:
[+] Running 6/6
Network librechat_default Created
Container chat-vectordb Started
Container chat-mongodb Started
Container chat-meilisearch Started
Container chat-rag-api Started
Container LibreChat StartedCheck that every container is healthy:
docker compose psYou should see five services in Up state. Tail the API logs to watch startup:
docker compose logs -f apiLook for lines like:
info: [Optional] Using Meilisearch at http://meilisearch:7700
info: Connected to MongoDB
info: Server listening on all interfaces at port 3080Press Ctrl+C to stop following the log (containers keep running).
A local smoke test:
curl -I http://127.0.0.1:3080Expected response:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8Step 9: Create the First Admin User
With ALLOW_REGISTRATION=true, you can register the first account through the browser -- but since Nginx is not yet configured, do it via the CLI instead. LibreChat ships a user-creation script:
docker compose exec api npm run create-userYou will be prompted for email, name, username, and password. The first user created through this script is automatically granted admin privileges.
Immediately after creating the admin account, set ALLOW_REGISTRATION=false in .env and restart:
docker compose restart apiFrom now on new users must be added via npm run create-user or invited through admin-configured SSO.
Step 10: Put Nginx + Let's Encrypt in Front
LibreChat should never be exposed on port 3080 directly. Put Nginx in front to handle TLS, gzip, rate limiting, and HTTP-to-HTTPS redirects.
Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginxCreate the site config:
sudo tee /etc/nginx/sites-available/librechat > /dev/null <<'EOF' server { listen 80; server_name chat.yourdomain.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; server_name chat.yourdomain.com;
# Certbot fills these in automatically ssl_certificate /etc/letsencrypt/live/chat.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/chat.yourdomain.com/privkey.pem;
# --- Hardening --- ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# --- Upload + streaming --- client_max_body_size 100m; proxy_read_timeout 600s; proxy_send_timeout 600s;
location / { proxy_pass http://127.0.0.1:3080; proxy_http_version 1.1; 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;
# WebSocket + SSE for streaming tokens proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; } } EOF
Enable the site and obtain a certificate:
sudo ln -s /etc/nginx/sites-available/librechat /etc/nginx/sites-enabled/
sudo nginx -t
sudo certbot --nginx -d chat.yourdomain.com
sudo systemctl reload nginxCertbot configures auto-renewal via a systemd timer -- verify with sudo systemctl list-timers | grep certbot.
Now open https://chat.yourdomain.com in your browser. You should see the LibreChat login page. Sign in with the admin account you created in Step 9.
Step 11: Enable RAG File Uploads
RAG (Retrieval-Augmented Generation) lets users upload PDFs, DOCX, CSVs, code, or Markdown and then chat over the contents. The default stack already includes the rag_api and vectordb (pgvector) services.
In .env, ensure the following are set:
RAG_API_URL=http://rag_api:8000
RAG_OPENAI_API_KEY=${OPENAI_API_KEY}
EMBEDDINGS_PROVIDER=openai
EMBEDDINGS_MODEL=text-embedding-3-small
RAG_UPLOAD_DIR=/app/uploadsIf you would rather keep embedding on-device (no OpenAI calls for embeddings), use the HuggingFace local provider:
EMBEDDINGS_PROVIDER=huggingface
EMBEDDINGS_MODEL=sentence-transformers/all-MiniLM-L6-v2Restart to pick up changes:
docker compose restart api rag_apiIn the UI you will now see a paperclip icon next to the chat input. Drag a PDF in, wait a few seconds for embedding, and then ask questions about it. The RAG service chunks the document, embeds each chunk, stores vectors in pgvector, and retrieves top-k chunks as context on each message.
Admins can monitor RAG from the logs:
docker compose logs -f rag_apiStep 12: Configure Agents and Presets
Presets
A preset is a reusable bundle of {model, system prompt, temperature, max tokens, tools}. Any user can save the current chat's settings as a preset from the dropdown next to the conversation title.
Admins can seed shared "global presets" by editing librechat.yaml:
modelSpecs:
enforce: false
prioritize: true
list:
- name: 'support-agent'
label: 'Customer Support Agent'
description: 'Friendly support tone, grounded in our help center'
default: false
preset:
endpoint: 'anthropic'
model: 'claude-3-5-sonnet-20241022'
promptPrefix: |
You are a senior support engineer at ACME Corp.
Reply in plain English, cite sources when relevant,
and never promise refunds without a ticket number.
temperature: 0.3
maxOutputTokens: 2000Reload:
docker compose restart apiAgents
The built-in agent builder lives at https://chat.yourdomain.com/c/new?endpoint=agents. To create one:
Agents can be shared organisation-wide by the user who created them (if the admin enabled sharing in librechat.yaml under actions.allowedDomains).
Upgrading LibreChat
Release cadence is roughly every 2-4 weeks. To upgrade:
cd /opt/librechatBack up first (see next section)
./backup.shPull the new code
git fetch --tags
git checkout v0.7.9 # replace with latest tagCheck for new env vars / yaml keys
diff .env .env.example
diff librechat.yaml librechat.example.yamlPull new images and recreate
docker compose pull
docker compose up -dTail logs to confirm the migration ran cleanly
docker compose logs -f apiMajor versions occasionally change the Meilisearch index version. The compose file names its volume after the version (meili_data_v1.12) so old data is preserved in the previous directory. After confirming the new one indexes correctly, you can delete the old directory to reclaim disk.
Backups and Disaster Recovery
Create /opt/librechat/backup.sh:
#!/usr/bin/env bash
set -euo pipefail
TS=$(date +%Y-%m-%d-%H%M)
DEST=/opt/librechat/backups/$TS
mkdir -p "$DEST"MongoDB dump
docker compose exec -T mongodb mongodump --archive --gzip > "$DEST/mongo.gz"pgvector dump (for RAG embeddings)
docker compose exec -T vectordb pg_dump -U myuser mydatabase | gzip > "$DEST/pgvector.sql.gz"Config + uploads
tar -czf "$DEST/config.tar.gz" .env librechat.yaml docker-compose.override.yml
tar -czf "$DEST/uploads.tar.gz" uploads imagesKeep last 14 days
find /opt/librechat/backups -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +Make it executable and schedule nightly:
chmod +x /opt/librechat/backup.sh crontab -eAdd:
0 3 * /opt/librechat/backup.sh >> /var/log/librechat-backup.log 2>&1
For off-site copies, sync /opt/librechat/backups to S3, Backblaze B2, or another VPS with rclone or restic.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
502 Bad Gateway from Nginx | LibreChat container not listening on 3080 | docker compose ps; tail api logs; ensure PORT=3080 in .env matches the compose port binding. |
| Login works but streaming stalls mid-response | Nginx buffering the SSE stream | Confirm proxy_buffering off; in the Nginx config and reload Nginx. |
| "Invalid CREDS_KEY length" on startup | Key is not exactly 64 hex chars | Regenerate with openssl rand -hex 32 and paste carefully (no line breaks). |
| "Invalid CREDS_IV length" on startup | IV must be exactly 32 hex chars (16 bytes) | Regenerate with openssl rand -hex 16. |
| Plugins tab is empty | No plugin-compatible model selected or no plugin keys set | Switch to a GPT-4 or Claude 3.5 Sonnet model; confirm at least one plugin key (DALL-E, SerpAPI, etc.) is present in .env. |
| RAG file uploads hang forever | rag_api cannot reach vectordb | docker compose logs rag_api; confirm both services are on the same compose network. |
| Ollama endpoint does nothing | Container cannot reach host | Check extra_hosts: - "host.docker.internal:host-gateway" in docker-compose.override.yml; curl http://host.docker.internal:11434 from inside the api container. |
| "429 Too Many Requests" from OpenAI | Provider rate limit, not LibreChat | Lower CONCURRENT_MESSAGE_MAX; upgrade your OpenAI tier. |
| Meilisearch uses excessive RAM | Index growing large with long conversations | Cap the index with MEILI_MAX_INDEXING_MEMORY=1Gb in the Meilisearch service env. |
Registration open despite ALLOW_REGISTRATION=false | Container did not restart after .env change | docker compose restart api -- env is only read on container start. |
Useful diagnostic commands
# Health of every container
docker compose psCombined logs (last 200 lines)
docker compose logs --tail=200Just the main API
docker compose logs -f apiExec into the API container
docker compose exec api shTest Ollama reachability from inside the container
docker compose exec api sh -c 'apk add --no-cache curl 2>/dev/null; curl -s http://host.docker.internal:11434/api/tags'FAQ
Does LibreChat work without any commercial API keys?
Yes. If you configure only the Ollama custom endpoint (Step 7) and leave all cloud provider keys blank, LibreChat becomes a pure local-LLM chat UI backed by your own models. RAG embeddings can also be done locally using EMBEDDINGS_PROVIDER=huggingface. The only thing that degrades is that features depending on OpenAI (DALL-E, Whisper, cloud-hosted agents) will not work.
How is LibreChat different from Open WebUI?
Both are ChatGPT-style frontends for self-hosting, but they target different users. Open WebUI is Ollama-first, with superb local-model management and a simple single-user-by-default experience -- see our Open WebUI install guide. LibreChat is provider-agnostic (any LLM), has deeper multi-user/SSO support, includes its own agent builder and plugin system, and offers features like branching conversations and preset sharing. If you want a team-ready portal with commercial API integrations, LibreChat is the better fit. If you want the cleanest Ollama experience for one or two users, Open WebUI is lighter.
Can I import my existing ChatGPT conversations?
Yes. LibreChat supports importing from OpenAI's ChatGPT export (the conversations.json file you get when you request your data from chat.openai.com). In the UI, go to Settings > Data Controls > Import Conversations and upload the file. The importer converts the ChatGPT format into LibreChat's internal schema and preserves thread structure.
How many concurrent users can one VPS handle?
The bottleneck is almost never LibreChat itself -- the Node backend is light -- it is MongoDB memory, Meilisearch indexing, and the RAM footprint of any local models. On the recommended CloudCore Professional (6 vCPU, 12 GB RAM) without local Ollama, expect comfortable performance for 20-30 concurrent chatters hitting cloud APIs. Add Ollama with a 7B model and the practical ceiling drops to about 5-10 concurrent users on that plan. Scale up to 16 GB or 32 GB RAM if you expect heavy RAG usage with large documents.
Does LibreChat support SSO / OIDC?
Yes. LibreChat supports Google, GitHub, Discord, Facebook, and Apple OAuth out of the box, plus LDAP and generic OpenID Connect for enterprise SSO providers like Okta, Auth0, Authelia, Authentik, and Keycloak. Configure OIDC by setting OPENID_URL, OPENID_CLIENT_ID, OPENID_CLIENT_SECRET, and OPENID_SCOPE in .env.
Is there an official mobile app?
Not as of v0.7.x. However, LibreChat is a PWA (Progressive Web App) -- open the site in mobile Safari or Chrome and "Add to Home Screen" for a near-native experience with offline shell and push notifications. The official docs track a native mobile roadmap at librechat.ai/docs.
Next Steps
With LibreChat running cleanly behind TLS, here are practical follow-ups:
- Add local models with Ollama -- Run Llama 3.1, Mistral, or Gemma on the same server and connect them through the custom endpoint. Follow How to install Ollama on Ubuntu 24.04 and jump back to Step 7 of this guide.
- Compare with Open WebUI -- If your team is Ollama-first and does not need cloud provider integrations, try Open WebUI on a second port for a lighter experience.
- Containerise everything else -- If this is your first Docker stack on the server, review How to install Docker on Ubuntu 24.04 for best practices around log rotation, user namespaces, and daemon hardening.
- Add observability -- Pipe LibreChat's
logs/directory into Loki, Grafana, or a hosted log service. For container metrics use cAdvisor + Prometheus. Set alerts on MongoDB disk usage and Meilisearch index size.
- Harden with Fail2Ban and CrowdSec -- Nginx is internet-facing and will be probed within minutes of DNS propagation. CrowdSec gives you community-sourced IP blocklists without the rule-writing overhead of classic Fail2Ban.
- Read the official docs -- LibreChat is under rapid development; the canonical reference is librechat.ai/docs, which covers config schema changes, new endpoints, and agent/plugin authoring.
Running LibreChat for your team?>
Our CloudCore Professional plan is a good fit for LibreChat with 5-20 active users, cloud provider APIs, and RAG enabled: 6 vCPU, 12 GB RAM, 100 GB NVMe, unmetered bandwidth -- EUR 19.99/month. For deployments that also host local models on the same box, step up to a higher-memory plan.>
See VPS plans