Skip to main content
Waterline is designed to be self-hosted. The Docker Compose stack bundled with the project runs every required service — API, frontend, Postgres, Redis, and ChromaDB — so you can have a fully working instance on a single machine or a cloud VM. This page covers the configuration decisions you need to make before going to production, including which database backend to use, how to set your public URLs, and where to store vector data.
This page focuses on environment variable configuration. For step-by-step setup instructions, see the Docker and Database pages in the self-hosting section.

Choose a backend

Waterline supports two authentication and database backends, controlled by the BACKEND variable.

Set production URLs

In production you must set the correct public-facing URLs so that OAuth callbacks and API requests resolve correctly.
ENVIRONMENT=production
DOMAIN=your-domain.com
FRONTEND_URL=https://your-domain.com
API_BASE_URL=https://api.your-domain.com
Setting ENVIRONMENT=production enables Sentry error reporting (if SENTRY_DSN is set) and tightens CORS policy. Do not run a production instance with ENVIRONMENT=development.

Full production configuration example

# Environment
ENVIRONMENT=production
DOMAIN=your-domain.com
FRONTEND_URL=https://your-domain.com
API_BASE_URL=https://api.your-domain.com

# Backend
BACKEND=postgres
DATABASE_URL=postgresql://waterline:password@postgres:5432/waterline
JWT_SECRET=<output of: openssl rand -hex 32>

# Redis
REDIS_URL=redis://redis:6379

# LLM — choose your setup, see the LLM Providers page
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...

# Embeddings
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
OPENAI_API_KEY=sk-...

# GitHub OAuth
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_REDIRECT_URI=https://api.your-domain.com/api/connect/github/callback

# Jira OAuth
JIRA_CLIENT_ID=...
JIRA_CLIENT_SECRET=...
JIRA_REDIRECT_URI=https://api.your-domain.com/api/connect/jira/callback

Redis

Redis is required. It stores ticket progress cache, symbol search cache, and background job queues. The Docker Compose file provides a Redis container automatically — no configuration changes are needed for local development. In production, set REDIS_URL to point at your Redis instance:
REDIS_URL=redis://redis:6379
If you’re running Redis on a managed service (Upstash, Redis Cloud, etc.), use the connection URL provided by that service.

ChromaDB

Waterline uses ChromaDB as its vector store for symbol and file embeddings. There are two deployment options:
By default, ChromaDB runs embedded inside the API container and persists data to a local directory. This requires no extra configuration and works well for a single-instance deployment.
CHROMA_PATH=./chroma
The Docker Compose file already mounts ./chroma to /app/chroma in the container. For production, make sure this path maps to a persistent volume so your vector index survives container restarts.

Repo size limits

Waterline caps how much of each repository it indexes to prevent unexpectedly large LLM bills when a user connects a large monorepo.
REPO_MAX_FILES=2000
REPO_MAX_SYMBOLS=15000
Indexing stops once either limit is reached. Raise these values if you need full coverage of larger repositories, but be aware that a higher symbol count means proportionally more LLM calls during the initial index.

Pre-launch security checklist

Before making your instance publicly accessible:
  • JWT_SECRET is at least 32 characters and was generated randomly (not manually typed)
  • ENVIRONMENT=production is set
  • All OAuth redirect URIs use https://
  • The GitHub webhook endpoint (GITHUB_WEBHOOK_PATH) is publicly reachable so GitHub can POST push events to it
  • Postgres and Redis are not exposed to the public internet — use internal Docker networking or a private VPC
  • SUPABASE_SERVICE_ROLE_KEY (if using Supabase backend) is not present in any frontend environment or public config
  • SENTRY_DSN is set if you want error tracking in production