AILLMDockerAI Coding Agents

LibreChat with Docker: One Chat App for Ollama and Cloud Models, with Agents and RAG (Linux, Windows, Mac)

Before you start

  • 16 min read
  • 15 to run in terminal
  • 1 file content

Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#

LibreChat is a free, open-source chat website you host yourself, and it talks to Ollama on your own computer and to cloud models such as OpenAI or Anthropic from one window.

One login, one chat history, many models. You can switch from a local Llama to a cloud model in the middle of your day. It also gives you agents (a chat with its own instructions and tools), file search over your own documents (RAG) and support for MCP tools. LibreChat is only the chat layer: Ollama or the cloud provider still runs the model.

WhatValue
Version usedv0.8.8 (GitHub release of 2026-10-01; GitHub still labels it "Pre-release", as it did v0.8.7)
App imageghcr.io/librechat-ai/librechat:v0.8.8 (tag confirmed on 2026-10-26)
Time neededAbout 15-25 minutes, mostly image downloads
Port3080 (the chat website)
Official docslibrechat.ai/docs

Why v0.8.8? We checked the issue tracker and discussions for this release. We found no repeated install failures and no data loss. We found feature-specific bugs, mostly around agents, MCP tools and file attachments (see Troubleshooting). Plain chat, Ollama and RAG are not in that list. So we use the latest release. If you rely on MCP tools, test them before you trust them.

How it fits together#

Your browser talks to the LibreChat app on port 3080, which saves chats in MongoDB, indexes files through the RAG API, and sends questions to Ollama or to a cloud model.

How LibreChat fits together: you open the chat website on port 3080; the LibreChat app saves accounts and chats in MongoDB, passes uploaded files to the optional RAG API which stores vectors in pgvector, sends questions to Ollama on your computer at host.docker.internal port 11434, and optionally to cloud models with an API key

Dashed boxes are optional. A fifth container, Meilisearch, makes your chat history searchable and is not drawn.

Before you start#

You need Docker with Compose 2.24.4 or newer, Git, and Ollama running on the same computer.

SystemRequirements
LinuxGit, Docker Engine or Docker Desktop, 4 GB RAM free for Docker plus whatever your Ollama models need
WindowsGit, Docker Desktop with the WSL2 backend (Linux containers), an Ubuntu WSL distro
MacGit, Docker Desktop for Mac

LibreChat itself needs no GPU. The docs name 1 GiB RAM and 1 vCPU as the minimum for the containers; local models need their own memory on top. The MongoDB image needs a CPU with AVX (see Troubleshooting if yours has none).

Check your tools:

Run in terminalbash
git --version
docker --version
docker compose version
  • [ ] Compose is 2.24.4 or newer (we use the !override feature)
  • [ ] Port 3080 is free
  • [ ] Ollama is installed and works (ollama list runs)
  • [ ] For the Traefik section only: a domain, DNS and ports 80 and 443

Not run by us on all three systems: the steps follow the official LibreChat docs and the real v0.8.8 files (docker-compose.yml, .env.example, librechat.example.yaml), checked on 2026-10-26.

Step 1: Get LibreChat v0.8.8 into one folder#

Clone the exact release into ~/docker_volumes/librechat/app so the data sits under one folder.

LibreChat's Compose file keeps data in folders next to itself (data-node, uploads, images, logs, meili_data_v1.35.1) and in two Docker volumes. Cloning into ~/docker_volumes/librechat/app puts it all under ~/docker_volumes/librechat. Backups go next to it. The upstream repository moved to the LibreChat-AI organization, so use that address.

Linux#

Run in terminalbash
mkdir -p ~/docker_volumes/librechat/backups
git clone --branch v0.8.8 --single-branch https://github.com/LibreChat-AI/LibreChat.git ~/docker_volumes/librechat/app
cd ~/docker_volumes/librechat/app
git describe --tags --exact-match
cp .env.example .env
chmod 600 .env

Windows (PowerShell)#

Open your Ubuntu shell from PowerShell and run the Linux commands inside it. Keep the files in the WSL home folder, not under /mnt/c, because databases are slow and fragile on Windows folders. Docker Desktop must have WSL integration switched on for that distro.

Run in terminalpowershell
wsl -d Ubuntu

Mac (Terminal)#

Same commands as Linux:

Run in terminalbash
mkdir -p ~/docker_volumes/librechat/backups
git clone --branch v0.8.8 --single-branch https://github.com/LibreChat-AI/LibreChat.git ~/docker_volumes/librechat/app
cd ~/docker_volumes/librechat/app
git describe --tags --exact-match
cp .env.example .env
chmod 600 .env

Check it worked: git describe prints v0.8.8.

Step 2: Set your secrets in .env#

Fill the empty secret lines with random values and set your user ID.

CREDS_KEY (64 hex characters) and CREDS_IV (32) encrypt the API keys users store. JWT_SECRET and JWT_REFRESH_SECRET sign logins. MEILI_MASTER_KEY protects search. UID and GID make the containers write files as you. Back these values up: if you lose CREDS_KEY or CREDS_IV, stored keys cannot be read again, and changing them does not re-encrypt old records.

Linux#

Run in ~/docker_volumes/librechat/app:

Run in terminalbash
sed -i.bak \
  -e "s|^CREDS_KEY=.*|CREDS_KEY=$(openssl rand -hex 32)|" \
  -e "s|^CREDS_IV=.*|CREDS_IV=$(openssl rand -hex 16)|" \
  -e "s|^JWT_SECRET=.*|JWT_SECRET=$(openssl rand -hex 32)|" \
  -e "s|^JWT_REFRESH_SECRET=.*|JWT_REFRESH_SECRET=$(openssl rand -hex 32)|" \
  -e "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|" \
  -e "s|^# UID=.*|UID=$(id -u)|" -e "s|^# GID=.*|GID=$(id -g)|" .env
rm .env.bak
printf '%s\n' 'EMBEDDINGS_PROVIDER=ollama' 'OLLAMA_BASE_URL=http://host.docker.internal:11434' 'EMBEDDINGS_MODEL=nomic-embed-text' >> .env
grep -c -E '^(CREDS_KEY|CREDS_IV|JWT_SECRET|JWT_REFRESH_SECRET|MEILI_MASTER_KEY)=.+' .env

Windows (PowerShell)#

Run the Linux block inside the WSL shell (openssl is part of Ubuntu).

Mac (Terminal)#

Same commands as Linux (openssl is already on macOS; the -i.bak form works with the Mac sed too).

Check it worked: the last command prints 5. Run the block only once. Never commit .env or paste it into a chat. The three EMBEDDINGS_* lines are for local document search (Step 6).

Step 3: Add an override file and pin the image#

Keep upstream's docker-compose.yml as it is and put your changes in docker-compose.override.yml.

The upstream file uses a moving image tag (librechat-dev:latest) and publishes port 3080 on every network interface. The override pins the release, publishes 3080 on this computer only, mounts your librechat.yaml, and switches the RAG API to the full image that local embeddings need. Neither file has the obsolete version: line.

Linux#

Run in terminalbash
printf '%s\n' \
'services:' \
'  api:' \
'    image: ghcr.io/librechat-ai/librechat:v0.8.8' \
'    ports: !override' \
'      - "127.0.0.1:3080:3080"' \
'    volumes:' \
'      - type: bind' \
'        source: ./librechat.yaml' \
'        target: /app/librechat.yaml' \
'  rag_api:' \
'    image: registry.librechat.ai/librechat-ai/librechat-rag-api-dev:latest' \
'    extra_hosts:' \
'      - "host.docker.internal:host-gateway"' > docker-compose.override.yml

Windows (PowerShell)#

Run the Linux block inside the WSL shell.

Mac (Terminal)#

Same commands as Linux.

Check it worked: docker compose config --quiet prints nothing. Do not run plain docker compose config and share the result, it contains your secrets. The RAG image has only a latest tag (the registry lists nothing newer than v0.8.0), so it cannot be pinned.

Step 4: Point LibreChat at Ollama with librechat.yaml#

Create librechat.yaml with a custom endpoint that uses host.docker.internal:11434/v1.

Inside a container, localhost is the container itself, not your computer. Docker's special name host.docker.internal points at your computer. The apiKey must not be empty, even though Ollama ignores it. fetch: true lists the models you have pulled. The version: value is the schema version shipped with v0.8.8.

Linux#

Run in terminalbash
printf '%s\n' \
'version: 1.3.17' \
'cache: true' \
'endpoints:' \
'  custom:' \
'    - name: "Ollama"' \
'      apiKey: "ollama"' \
'      baseURL: "http://host.docker.internal:11434/v1"' \
'      models:' \
'        default: ["llama3.2:latest"]' \
'        fetch: true' \
'      titleConvo: true' \
'      titleModel: "current_model"' \
'      modelDisplayLabel: "Ollama"' > librechat.yaml
ollama pull llama3.2
ollama pull nomic-embed-text

Windows (PowerShell)#

Create the file inside the WSL shell with the block above. Pull the models in PowerShell if Ollama runs on Windows:

Run in terminalpowershell
ollama pull llama3.2
ollama pull nomic-embed-text

Mac (Terminal)#

Same commands as Linux.

Replace llama3.2 with a model that fits your hardware. titleModel: "current_model" stops LibreChat from loading a second model just to name chats.

Let the container reach Ollama. By default Ollama listens on 127.0.0.1 only. On Docker Desktop (Windows, Mac) the host name often works as it is. On Linux you usually must make Ollama listen on more than loopback, for example OLLAMA_HOST=0.0.0.0:11434 in the Ollama service environment. The docs warn that Ollama's API has no login, so anyone who can reach port 11434 can use and delete your models. Block 11434 with a firewall from other computers, or bind it only to your Docker network's gateway address.

Step 5: Start LibreChat#

Pull the images and start the five services you need.

We name the services on purpose. The optional admin panel container stays off, because it refuses to start until you set ADMIN_PANEL_SESSION_SECRET.

Linux#

Run in terminalbash
docker compose pull api mongodb meilisearch vectordb rag_api
docker compose up -d api mongodb meilisearch vectordb rag_api
docker compose ps
docker compose logs --tail=50 api

Windows (PowerShell)#

Run the same commands in the WSL shell.

Mac (Terminal)#

Same commands as Linux.

Check it worked: docker compose ps lists five running services and http://localhost:3080 shows the LibreChat login page. The first start takes a few minutes.

Step 6: Create your account and test every part#

The first account you register becomes the administrator, so register yourself before anyone else can.

  1. Open http://localhost:3080 and choose Sign up. There is no default login.
  2. Pick the Ollama endpoint in the model menu and send a short message.
  3. Attach a small, non-sensitive text file to a chat and ask about it. This tests the RAG API and the embedding model.
  4. Open the Agents builder, make an agent with a name, instructions, your Ollama model and the File Search capability, and ask it about the same file.
  5. Run docker compose restart and check your chats are still there.

Then close sign-up. In .env change ALLOW_REGISTRATION=true to ALLOW_REGISTRATION=false and recreate the app container.

Linux#

Run in terminalbash
sed -i.bak 's|^ALLOW_REGISTRATION=.*|ALLOW_REGISTRATION=false|' .env && rm .env.bak
docker compose up -d --force-recreate api

Windows (PowerShell)#

Run the Linux block in the WSL shell.

Mac (Terminal)#

Same commands as Linux.

Check it worked: a private browser window no longer offers to sign up. To add a second user later, switch it back on for a minute.

Cloud models. Add a key to .env, for example OPENAI_API_KEY=<YOUR_KEY> or ANTHROPIC_API_KEY=<YOUR_KEY>, recreate api, and the provider shows up in the model menu. A question sent to a cloud model leaves your computer.

MCP tools (optional). LibreChat can use MCP servers, configured under mcpServers: in librechat.yaml (the shipped librechat.example.yaml in your folder shows the exact shape). A server on your own computer needs its host:port listed under mcpSettings: allowedAddresses:. Add one server at a time and test it. Do not give an agent a shell or file access you would not give a stranger.

Put it behind HTTPS with Traefik#

On a server with a domain, let Traefik publish LibreChat over HTTPS and close the local port.

This assumes Traefik v3 already runs with the Docker provider on an external network named proxy, with an entrypoint websecure and a certificate resolver (the official docs call it leresolver). Use your own names. Local-only users can skip this section. Merge this into the existing api: block of docker-compose.override.yml (a service name may appear only once):

File contentyaml
services:
  api:
    ports: !override []
    networks:
      - default
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.librechat.rule=Host(`chat.<your-domain>`)"
      - "traefik.http.routers.librechat.entrypoints=websecure"
      - "traefik.http.routers.librechat.tls=true"
      - "traefik.http.routers.librechat.tls.certresolver=<your-resolver>"
      - "traefik.http.services.librechat.loadbalancer.server.port=3080"
networks:
  proxy:
    external: true

Create the network once if needed (docker network create proxy). In .env set DOMAIN_CLIENT=https://chat.<your-domain> and DOMAIN_SERVER=https://chat.<your-domain>; TRUST_PROXY=1 is already the default and fits one proxy in front. Then docker compose up -d. Do not copy --api.insecure=true from the official sample Traefik command, it opens the Traefik dashboard without a login.

Check it worked: curl -I https://chat.<your-domain>/ answers, and sign-up stays closed.

Security and testing#

The upstream setup starts MongoDB without a password, and Ollama has no login, so the network is your protection.

ControlHow
SecretsIn .env only, chmod 600 .env, never in Git or in librechat.yaml (use ${VARIABLE} there)
Sign-upALLOW_REGISTRATION=false after you made your account
NetworkPort 3080 on 127.0.0.1, or no host port behind Traefik; never forward MongoDB, Meilisearch, the RAG API or Ollama
Agents and MCPStart private, add one tool at a time
LogsRemove keys before you share a log

Keep off the internet: port 3080 (without HTTPS and a login), 11434, MongoDB, the RAG API and the admin panel. Plugin command hooks are opt-in in v0.8.8; leave them off. One discussion reports that they may fail open when bash is missing from the image, so never rely on them as your only guard.

Quick tests after every change:

Run in terminalbash
docker compose ps
docker compose logs --tail=100 api
docker compose exec api node -e "fetch('http://host.docker.internal:11434/v1/models').then(r=>console.log(r.status))"

The last line should print 200. It tests container-to-Ollama reachability and assumes Node is in the app image, which it is for a Node app.

Using LibreChat for RAG and agents#

RAG means LibreChat finds the best passages of your files and gives them to the model with your question.

With the Step 2 settings, nomic-embed-text on Ollama turns your files into vectors, the RAG API stores them in pgvector, and every new message in a chat with a file looks them up. Keep your answering model local too if you want the passages to stay on your computer. Pick the embedding model once: changing it later makes old vectors useless, so re-upload your files if you switch.

An agent is a saved chat setup: name, instructions, model and the tools it may use. Switch on File Search for document questions. Tool use depends on the model, so a small local model may ignore tools that a cloud model uses well.

Troubleshooting#

ProblemSolution
bind: address already in usePort 3080 is taken. Set PORT=3081 in .env and restart, or use ports: !override with "127.0.0.1:3081:3080" in the override
Containers exit right after startdocker compose logs api: look for bad YAML in librechat.yaml, a missing .env, or Docker not running
MongoDB crashes at startYour CPU has no AVX. Add mongodb: with image: mongo:4.4.18 to the override (official workaround)
Ollama list is emptyCheck baseURL, the non-empty apiKey, that Ollama listens beyond loopback, and the reachability test above. v0.8.8 blocks private addresses for user-provided URLs; the docs do not say a fixed baseURL like ours is affected, but if it stays blocked add endpoints: then allowedAddresses: with - 'host.docker.internal:11434' at the top level of librechat.yaml (the shipped example file shows this)
Admin panel missingIt only starts after you set ADMIN_PANEL_SESSION_SECRET and start it by name
Permission denied on data-node or uploadsUID and GID in .env do not match your user; fix them and the folder owner, never chmod 777
Tool "get_computer_system" not foundReported 2026-10-23 with Ollama and MCP on v0.8.8; maintainers asked for logs, no fix known. Test one server and one tool
AgentToolInitializationErrorReported 2026-10-16: an OAuth MCP server is forced onto a model spec and the user has not authorized it. Authorize it or do not force it
The model provider could not complete this request.Reported 2026-10-08: an agent permission error can look like a provider error. Check the agent's sharing and permissions first
400 Unsupported chat content part typeA PDF was sent as a native file part to a vLLM or llama.cpp endpoint. Start a new chat and use File Search instead
Message pruning removed all messages as none fit in the context window.Attachments plus history exceed the context. Remove attachments or use a model with more context

Diagnostics: docker compose ps, docker compose logs --tail=200 api, docker compose logs --tail=200 rag_api vectordb.

Known bugs#

The tracker shows open reports on v0.8.8 about MCP tools with Ollama, OAuth MCP servers and generated-file delivery. Check the issue list before you depend on those features.

Updates and backups#

Back up MongoDB, the vector database and your files, test a restore, then change the version.

A MongoDB dump alone is not a backup: uploads, the vector database and your .env matter too. Keep CREDS_KEY and CREDS_IV with the backup.

Linux#

Run in terminalbash
cd ~/docker_volumes/librechat/app
STAMP=$(date +%Y%m%d-%H%M%S)
B=../backups/$STAMP; mkdir -p "$B"
docker compose exec -T mongodb mongodump --db LibreChat --archive --gzip > "$B/mongodb.archive.gz"
docker compose exec -T vectordb pg_dump -U myuser -d mydatabase -Fc > "$B/rag.dump"
tar -czf "$B/files-and-config.tar.gz" .env librechat.yaml docker-compose.override.yml uploads images
git rev-parse HEAD > "$B/git-commit.txt"
ls -l "$B"

Windows (PowerShell)#

Run the Linux block in the WSL shell. Copy the finished backups folder to another computer. To schedule it, save the block as a script and use Task Scheduler to run wsl -d Ubuntu -- bash <path-to-your-script> at 03:00.

Mac (Terminal)#

Same commands as Linux. Schedule with cron at 03:00 (0 3 * * *).

myuser and mydatabase are the names in the v0.8.8 Compose file. Copy the backups off the machine; they hold your conversations and keys.

Restore test. Restore into a throwaway MongoDB container, never into the live one. Replace <STAMP> with your backup folder name:

Run in terminalbash
docker run -d --name lc-restore-test mongo:8.0.20
sleep 8
docker exec -i lc-restore-test mongorestore --archive --gzip < ../backups/<STAMP>/mongodb.archive.gz
docker exec lc-restore-test mongosh --quiet --eval 'db.getSiblingDB("LibreChat").users.countDocuments()'
docker rm -f lc-restore-test

The number printed is your user count. If it is not zero, the dump is readable. A real restore also needs the files archive and the same .env.

Updating. Read the release notes first and back up. Then:

Run in terminalbash
git fetch --tags
git checkout --detach <NEW_TAG>

Edit the image tag in docker-compose.override.yml to <NEW_TAG>, compare .env.example with your .env for new settings, then:

Run in terminalbash
docker compose pull api mongodb meilisearch vectordb rag_api
docker compose up -d api mongodb meilisearch vectordb rag_api
docker compose logs --tail=100 api

Do not use git pull on a tag checkout, and never run docker compose down -v as an update step: it deletes the Docker volumes with your chats and vectors. The registry already holds v0.8.9-rc1; wait for a final tag.

Performance and resources#

LibreChat itself is light; the local model and the document indexing are what use your memory and CPU.

We did not measure resource use on a test machine for this guide, so there are no RAM numbers here. The docs name 1 GiB RAM and 1 vCPU as the minimum for the containers and quote about 4 GB of memory for Docker Desktop on Mac and Linux and 8 GB on Windows. Add what your Ollama model needs.

  • Use titleModel: "current_model" so no second model is loaded for chat titles.
  • Start with one local chat model and one embedding model, and test with small files first.
  • Large attachments can fill the context window even when your typed question is short.
  • Watch real use with docker stats.

FAQ#

Does LibreChat run the models itself? No. It sends your questions to Ollama or a cloud provider. It needs no GPU, your models might.

Can I use local and cloud models together? Yes. Add the Ollama endpoint and a cloud key, then choose a model per chat. Cloud chats leave your computer.

Can RAG stay fully local? Yes, with Ollama embeddings (nomic-embed-text) and a local answering model. Cloud tools or cloud models break that.

Why does Ollama work on my computer but not inside LibreChat? Inside a container localhost is the container. Use host.docker.internal and make sure Ollama listens beyond 127.0.0.1, while keeping port 11434 closed to other computers.

Is the pinned version enough for a repeatable setup? Only for the app. The RAG API image is latest, and the other images are pinned by the upstream file. Note the image digests (docker compose images) if you need exact repeatability.

Sources#