✦ AI · Query explanation
A copy-paste docker-compose.yml: pulls the published ghcr.io image with every environment variable (auth, OIDC SSO, storage, AI/LLM, seed) — self-host in one command.
docker_compose.sql
SELECT variable, default, description FROM env_vars; 21 rows | 3 cols
6ms
Docker Compose example
One command to self-host LibreDB Studio — pulls the published ghcr.io image, with every environment variable.
Quick start
curl -O https://libredb.org/docker-compose.example.yml
mv docker-compose.example.yml docker-compose.yml
# set JWT_SECRET, ADMIN_PASSWORD and USER_PASSWORD in .env
docker compose up -d
# open http://localhost:3000
That's it — LibreDB Studio is now running at
http://localhost:3000. Log in with the admin credentials from your
.env file.
The full docker-compose.example.yml
# =============================================================================
# LibreDB Studio — Ready-to-use Docker Compose
# =============================================================================
# Pulls the published image (ghcr.io/libredb/libredb-studio:latest) — no source
# build required. Works on any Docker host and PaaS that consumes a plain
# docker-compose.yml (Dokploy, Coolify, Portainer, etc.).
#
# Quick start:
# 1. cp docker-compose.example.yml docker-compose.yml
# 2. cp .env.example .env # then set at least JWT_SECRET / passwords
# 3. docker compose up -d
# 4. open http://localhost:3000
#
# Every supported environment variable is listed below. Commonly-used ones are
# active; less-frequently-used ones are shown commented out — uncomment as needed.
# Secrets are read from the .env file via ${VAR} interpolation and are never
# hardcoded in this file.
# =============================================================================
services:
libredb-studio:
image: ghcr.io/libredb/libredb-studio:latest
container_name: libredb-studio
restart: unless-stopped
ports:
- "3000:3000"
# Uncomment if you enable the bundled PostgreSQL service below:
# depends_on:
# libredb-postgres:
# condition: service_healthy
environment:
# -----------------------------------------------------------------------
# AUTHENTICATION (required)
# -----------------------------------------------------------------------
ADMIN_EMAIL: ${ADMIN_EMAIL:[email protected]} # admin: full access + maintenance tools
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?set ADMIN_PASSWORD in .env}
USER_EMAIL: ${USER_EMAIL:[email protected]} # user: query execution only
USER_PASSWORD: ${USER_PASSWORD:?set USER_PASSWORD in .env}
# JWT signing secret — min 32 chars. Generate: openssl rand -base64 32
JWT_SECRET: ${JWT_SECRET:?set JWT_SECRET in .env (min 32 chars)}
# Auth provider: "local" (default, email/password) or "oidc" (SSO)
NEXT_PUBLIC_AUTH_PROVIDER: ${NEXT_PUBLIC_AUTH_PROVIDER:-local}
# -----------------------------------------------------------------------
# OIDC SSO (only when NEXT_PUBLIC_AUTH_PROVIDER=oidc)
# Auth0 / Keycloak / Okta / Azure AD / Zitadel
# -----------------------------------------------------------------------
# OIDC_ISSUER: ${OIDC_ISSUER} # must serve /.well-known/openid-configuration
# OIDC_CLIENT_ID: ${OIDC_CLIENT_ID}
# OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
# OIDC_SCOPE: ${OIDC_SCOPE:-openid profile email}
# OIDC_ROLE_CLAIM: ${OIDC_ROLE_CLAIM:-} # e.g. realm_access.roles (Keycloak), groups (Okta)
# OIDC_ADMIN_ROLES: ${OIDC_ADMIN_ROLES:-admin}
# -----------------------------------------------------------------------
# STORAGE — where connections/config are persisted (server-side)
# "local" (default) browser localStorage, zero config
# "sqlite" server file, single-node persistent (uncomment volume below)
# "postgres" multi-node persistent (uncomment the postgres service below)
# -----------------------------------------------------------------------
STORAGE_PROVIDER: ${STORAGE_PROVIDER:-local}
# STORAGE_SQLITE_PATH: ${STORAGE_SQLITE_PATH:-/app/data/libredb-storage.db}
# STORAGE_POSTGRES_URL: ${STORAGE_POSTGRES_URL:-postgresql://postgres:postgres@libredb-postgres:5432/libredb_storage?sslmode=disable}
# -----------------------------------------------------------------------
# AI / LLM (optional) — provider: gemini | openai | ollama | custom
# -----------------------------------------------------------------------
# LLM_PROVIDER: ${LLM_PROVIDER:-gemini}
# LLM_API_KEY: ${LLM_API_KEY} # required for gemini/openai
# LLM_MODEL: ${LLM_MODEL:-gemini-2.5-flash}
# LLM_API_URL: ${LLM_API_URL} # ollama/custom only, e.g. http://host:11434/v1
# -----------------------------------------------------------------------
# SEED CONNECTIONS (optional) — pre-configure databases on boot.
# Uncomment the seed volume mount below, then provide seed-connections.yaml.
# Credentials referenced in that file via ${VAR} are read from this .env.
# -----------------------------------------------------------------------
# SEED_CONFIG_PATH: /app/config/seed-connections.yaml
# SEED_CACHE_TTL_MS: ${SEED_CACHE_TTL_MS:-60000}
# volumes:
# # SQLite storage persistence (STORAGE_PROVIDER=sqlite):
# - libredb-data:/app/data
# # Seed connections file (read-only):
# - ./seed-connections.yaml:/app/config/seed-connections.yaml:ro
# Image runs as node:24.16.0-trixie-slim (no curl/wget) — use Node's built-in fetch.
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://localhost:3000/api/db/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
# ---------------------------------------------------------------------------
# Optional: PostgreSQL backend for STORAGE_PROVIDER=postgres
# To enable: uncomment this service, the STORAGE_POSTGRES_URL env above,
# the depends_on block above, and the pgdata volume below.
# ---------------------------------------------------------------------------
# libredb-postgres:
# image: postgres:18
# container_name: libredb-postgres
# restart: unless-stopped
# environment:
# POSTGRES_USER: postgres
# POSTGRES_PASSWORD: postgres
# POSTGRES_DB: libredb_storage
# volumes:
# - pgdata:/var/lib/postgresql/data
# healthcheck:
# test: ["CMD-SHELL", "pg_isready -U postgres"]
# interval: 10s
# timeout: 5s
# retries: 5
# volumes:
# libredb-data: # SQLite storage persistence
# pgdata: # PostgreSQL storage persistence Environment variable reference
Every supported variable, grouped as in the file. Secrets are read from your
.env file via ${VAR} interpolation —
never hardcoded in the compose file.
Authentication (required)
| Variable | Default | Description |
|---|---|---|
ADMIN_EMAIL | [email protected] | Admin login — full access plus maintenance tools. |
ADMIN_PASSWORD | — (required) | Admin password. Set this in your .env file. |
USER_EMAIL | [email protected] | Standard user login — query execution only. |
USER_PASSWORD | — (required) | User password. Set this in your .env file. |
JWT_SECRET | — (required) | JWT signing secret, min 32 chars. Generate: openssl rand -base64 32 |
NEXT_PUBLIC_AUTH_PROVIDER | local | Auth mode: "local" (email/password) or "oidc" (SSO). |
OIDC SSO (when NEXT_PUBLIC_AUTH_PROVIDER=oidc)
| Variable | Default | Description |
|---|---|---|
OIDC_ISSUER | — | Issuer URL serving /.well-known/openid-configuration. |
OIDC_CLIENT_ID | — | OIDC client ID from your identity provider. |
OIDC_CLIENT_SECRET | — | OIDC client secret. |
OIDC_SCOPE | openid profile email | Requested OIDC scopes. |
OIDC_ROLE_CLAIM | — | Claim holding roles, e.g. realm_access.roles (Keycloak), groups (Okta). |
OIDC_ADMIN_ROLES | admin | Roles mapped to admin access. Works with Auth0, Keycloak, Okta, Azure AD, Zitadel. |
Storage — where connections & config persist
| Variable | Default | Description |
|---|---|---|
STORAGE_PROVIDER | local | "local" (browser localStorage, zero config), "sqlite" (single-node file), or "postgres" (multi-node). |
STORAGE_SQLITE_PATH | /app/data/libredb-storage.db | SQLite file path. Mount a volume to persist it. |
STORAGE_POSTGRES_URL | postgresql://…@libredb-postgres:5432/libredb_storage | PostgreSQL connection string for multi-node persistence. |
AI / LLM (optional)
| Variable | Default | Description |
|---|---|---|
LLM_PROVIDER | gemini | Provider: gemini | openai | ollama | custom. |
LLM_API_KEY | — | API key — required for gemini/openai. |
LLM_MODEL | gemini-2.5-flash | Model name to use for NL2SQL. |
LLM_API_URL | — | Base URL for ollama/custom, e.g. http://host:11434/v1 |
Seed connections (optional)
| Variable | Default | Description |
|---|---|---|
SEED_CONFIG_PATH | /app/config/seed-connections.yaml | Pre-configure databases on boot from a mounted YAML file. |
SEED_CACHE_TTL_MS | 60000 | Cache TTL for seeded connections, in milliseconds. |