No description
  • Go 84.7%
  • Jinja 14.9%
  • Dockerfile 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-24 16:12:44 +02:00
.gitea/workflows feat: initial config 2026-09-04 23:57:55 +02:00
defaults feat: librechat mcp fetch 2026-09-24 16:10:28 +02:00
files/otel/langfuse-fanout Prettified Code! 2026-09-04 21:59:57 +00:00
handlers feat: librechat mcp fetch 2026-09-24 16:10:28 +02:00
meta feat: initial config 2026-09-04 23:57:55 +02:00
tasks feat: librechat mcp fetch 2026-09-24 16:10:28 +02:00
templates feat: librechat mcp fetch 2026-09-24 16:10:28 +02:00
.gitignore feat: initial config 2026-09-04 23:57:55 +02:00
CHANGELOG.md [skip ci] updated changelog 2026-09-24 16:12:44 +02:00
LICENSE feat: initial config 2026-09-04 23:57:55 +02:00
README.md Prettified Code! 2026-09-22 13:11:37 +00:00

LibreChat

Deploys LibreChat via Docker Compose — API, bundled admin panel, MongoDB, Meilisearch, and a pgvector-backed RAG API — with an optional tenant-scoped Langfuse fanout gateway for multi-tenant observability.

Requirements

  • Docker
  • community.docker Ansible collection (>=5.2.0)

Variables

Variable Default Description
librechat_instance librechat Unique instance name. Used as Compose project name and a container-name prefix.
librechat_version latest Tag for registry.librechat.ai/danny-avila/librechat-dev, or sha256:<digest> to pin an exact build. See Notes - latest is not safe to rely on for a deployment that cares about reproducibility.
librechat_data_path /data/librechat Host path for persistent data (MongoDB, Meilisearch, pgvector, uploads, images, logs).
librechat_docker_path /docker/librechat Host path for the Compose file and rendered .env.
librechat_uid / librechat_gid 1000 / 1000 Host UID/GID the api/mongodb/meilisearch containers run as.
librechat_domain ~ Public domain for the app. When set, enables Traefik routing and joins traefik_web.
librechat_traefik_certresolver default Traefik certificate resolver for librechat_domain/librechat_admin_domain.
librechat_port ~ When set, publishes LibreChat on this host port (→ container port 3080) instead of using Traefik.
librechat_admin_domain ~ Public domain for the admin panel (independent of librechat_domain).
librechat_admin_port ~ When set, publishes the admin panel on this host port (→ container port 3000) instead of using Traefik.
librechat_admin_panel_session_secret ~ Required. Admin panel session encryption key (min 32 chars). Generate with openssl rand -hex 32.
librechat_search_enabled false Enables Meilisearch-backed full-text search. Requires librechat_meili_master_key.
librechat_meili_master_key ~ Required when search is enabled. Generate with openssl rand -hex 32.
librechat_custom_endpoint_enabled false Renders and mounts librechat.yaml with a single custom endpoint - replaces the built-in "openAI" endpoint, which always shows a hardcoded "OpenAI" name/icon regardless of what it's actually backed by. See Notes.
librechat_endpoint_name / librechat_endpoint_api_key / librechat_endpoint_base_url ~ Required when the custom endpoint is enabled.
librechat_endpoint_models [] Required (at least one) when the custom endpoint is enabled. Static model list shown in the picker.
librechat_endpoint_file_limit 20 Max file size (MB) the custom endpoint accepts. PDFs are always delivered as extracted text rather than natively - see Notes.
librechat_websearch_enabled false Enables web search in librechat.yaml: SearXNG + a Firecrawl-compatible scraper, no reranker, no third-party SaaS. Neither is deployed by this role - see Notes.
librechat_stt_enabled false Enables speech-to-text/text-to-speech in librechat.yaml via a speaches instance. Not deployed by this role - see Notes.
librechat_vectordb_db / librechat_vectordb_user librechat_rag / librechat_rag Postgres database/user for the RAG API's pgvector store (internal network only).
librechat_vectordb_pass ~ Required. Generate with openssl rand -hex 32.
librechat_rag_port 8000 Internal port the RAG API listens on.
librechat_rag_embeddings_provider / librechat_rag_openai_baseurl / librechat_rag_openai_api_key openai / http://embeddings-not-configured.invalid/v1 / "" rag_api's embeddings backend. Point librechat_rag_openai_baseurl at any OpenAI-compatible endpoint (e.g. an internal litellm instance) to keep uploaded file content off the real OpenAI API. See Notes.
librechat_rag_embeddings_model text-embedding-3-small Model name rag_api requests at librechat_rag_openai_baseurl. Must match a model_name that backend actually serves once the baseurl above is pointed somewhere real.
librechat_creds_key / librechat_creds_iv ~ Required. Encrypts stored provider credentials. Never change after first deploy. openssl rand -hex 32 / openssl rand -hex 16.
librechat_jwt_secret / librechat_jwt_refresh_secret ~ Required. Sign auth/session JWTs. openssl rand -hex 32 each.
librechat_langfuse_public_key / librechat_langfuse_secret_key / librechat_langfuse_base_url ~ / ~ / https://cloud.langfuse.com Central Langfuse project credentials. Leave librechat_langfuse_public_key unset to disable tracing.
librechat_langfuse_fanout_central_auth_header ~ Presence enables the tenant Langfuse fanout gateway (3 extra containers, built from files/otel/langfuse-fanout/). See Usage and Notes.
librechat_langfuse_fanout_* see defaults/main.yml Fanout gateway tuning (destinations, timeouts, batching, metrics token). Sensible defaults for the 3-region Langfuse Cloud preset (eu/us/jp).
librechat_env_extra "" Raw lines appended to the rendered .env for any of LibreChat's many optional settings not covered above (OAuth/SSO, SMTP, model provider keys, moderation, rate limits, MCP servers, ...). See dotenv docs.
librechat_uninstall false Stops and removes containers and the compose directory.
librechat_purge false Also removes the data directory (MongoDB, Meilisearch, pgvector, uploads, images, logs). Requires librechat_uninstall: true. Irreversible.

Usage

Minimal setup, behind Traefik:

librechat_domain: "chat.example.com"
librechat_admin_domain: "admin-chat.example.com"
librechat_admin_panel_session_secret: "{{ vault_librechat_admin_panel_session_secret }}"
librechat_vectordb_pass: "{{ vault_librechat_vectordb_pass }}"
librechat_creds_key: "{{ vault_librechat_creds_key }}"
librechat_creds_iv: "{{ vault_librechat_creds_iv }}"
librechat_jwt_secret: "{{ vault_librechat_jwt_secret }}"
librechat_jwt_refresh_secret: "{{ vault_librechat_jwt_refresh_secret }}"
librechat_env_extra: |
  OPENAI_API_KEY={{ vault_librechat_openai_api_key }}
  ALLOW_REGISTRATION=true

Without a reverse proxy (direct host ports instead of the _domain vars):

librechat_port: 3080
librechat_admin_port: 3000

Enabling tenant-scoped Langfuse fanout (per-tenant Langfuse projects + a central rollup):

librechat_langfuse_public_key: "{{ vault_librechat_langfuse_public_key }}"
librechat_langfuse_secret_key: "{{ vault_librechat_langfuse_secret_key }}"
librechat_langfuse_fanout_central_auth_header: "{{ vault_librechat_langfuse_fanout_central_auth_header }}"

Tenant Langfuse keys and destinations are not set here — each tenant's key and destination are configured at runtime through Settings > Langfuse in the app.

Uninstall

librechat_uninstall: true

Add librechat_purge: true to also delete MongoDB/Meilisearch/pgvector/uploads data.

Notes

  • rag_api ignores .env and LibreChat's OpenAI/embeddings settings entirely. Only the api container mounts the rendered .env file; rag_api gets exactly the environment vars set on it directly in compose.yml.j2. Its embeddings backend must therefore be configured via librechat_rag_embeddings_provider/librechat_rag_openai_baseurl/librechat_rag_openai_api_key — setting RAG_OPENAI_BASEURL/EMBEDDINGS_PROVIDER via librechat_env_extra has no effect on it. The defaults point nowhere resolvable on purpose (fail closed) rather than defaulting to the real OpenAI API, since rag_api falls back there itself when unconfigured — silently transmitting uploaded file content even without a valid key.
  • .env still carries the long tail. LibreChat has 250+ optional settings (OAuth providers, SMTP, moderation, rate limits, MCP servers, per-provider model config, ...). Rather than model every one as an Ansible variable, the handful that are required or security-sensitive for a working deploy are real librechat_* variables with asserts; everything else stays as commented reference in templates/.env.j2 (mirroring upstream's own .env.example), and librechat_env_extra is the escape hatch for whatever you actually need to turn on.
  • Admin panel is always its own origin. It gets its own _domain/_port pair rather than sharing librechat_domain, since it's a separate container with separate OAuth/SSO redirect handling (ADMIN_PANEL_URL).
  • MongoDB runs --noauth. It's only reachable on the internal Docker network (no host port published), matching upstream's own default; no credential is needed or configurable.
  • The Langfuse fanout gateway is bespoke, not upstream Langfuse. It's a small Go proxy LibreChat's own maintainers wrote to solve "route traces to a tenant's Langfuse project AND a central one" — Langfuse itself has no such concept, and there's no published image for it anywhere. This role vendors its source under files/otel/langfuse-fanout/ and builds it locally on the Docker host (deploy.yml passes --build whenever the fanout is enabled, so the image stays in sync with the vendored source on every run). See files/otel/langfuse-fanout/README.md for the full design and its limitations.
  • RAG API is not optional. vectordb + rag_api are always deployed, matching upstream's default compose stack.
  • librechat_version pins the api container's image (registry.librechat.ai/danny-avila/librechat-dev), defaulting to latest. That image only publishes latest and opaque per-commit git-sha tags - no semver/RC tags exist on it at all (those exist as git tags in the source repo, and as real published tags only on the separate, much-further-behind stable librechat image, not the -dev one this role uses). latest itself isn't safe to rely on for anything reproducible - confirmed live, it had already moved past a deployment's actual running build within weeks. Set librechat_version to sha256:<digest> (docker image inspect <image> --format '{{index .RepoDigests 0}}' on a host already running the build you want to pin to) to pin an exact one; the template switches from : to @ automatically for a sha256: value.
  • librechat_custom_endpoint_enabled's librechat.yaml is not a full LibreChat config surface. It renders exactly what upstream calls endpoints.custom (one endpoint) plus the fileConfig/webSearch/speech sections needed to support it - not a general-purpose librechat.yaml templating layer. librechat_websearch_enabled/librechat_stt_enabled assume a SearXNG+scraper / speaches instance already reachable on the same Docker network under fixed hostnames (searxng:8080, fastcrw:3000, whisper:8000) - this role deploys none of them; wire your own alongside this one under the same librechat_instance project name (matching container/network naming keeps them visually grouped in docker ps, though Compose will still warn about "orphan containers" since they're not in this compose.yml - harmless).