macOS Setup Guide
Step-by-step instructions for running Nyayrithm on macOS 13 Ventura or later (Intel and Apple Silicon). Default LLM: Gemini 2.5 Flash (free tier, no credit card required).
Contents
- Prerequisites
- Option A: Docker Desktop (recommended)
- Option B: Native (no Docker)
- Option C: Fully offline with Ollama
- Configuring LLM providers
- Verify the installation
- Apple Silicon notes
- Troubleshooting
Prerequisites
1. Homebrew
If not already installed:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Follow the post-install instructions to add Homebrew to your PATH (especially on Apple Silicon, adds /opt/homebrew/bin).
Verify:
brew --version # Homebrew 4.x
2. Git
macOS ships with Git, but the Homebrew version is newer:
brew install git
git --version # git version 2.47+
3. Xcode Command Line Tools
Required for native Python extensions:
xcode-select --install
Option A: Docker Desktop (recommended)
Step 1: Install Docker Desktop
Download from https://www.docker.com/products/docker-desktop/
- Apple Silicon (M1/M2/M3/M4): download the Apple Silicon
.dmg - Intel Mac: download the Intel
.dmg
Open the .dmg, drag Docker to Applications, launch it, and wait for the status bar icon to show “Docker Desktop is running”.
Verify:
docker --version # Docker version 27+
docker compose version # Docker Compose version v2.30+
Step 2: Install Node.js 24 LTS + Bun
brew install node@24
echo 'export PATH="/opt/homebrew/opt/node@24/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Install Bun (JS runtime + package manager)
curl -fsSL https://bun.sh/install | bash
Verify:
node --version # v24.x.x
bun --version # 1.x.x
Step 3: Clone and configure
git clone https://github.com/Aayush-Joshi-01/nyayrithm.git
cd nyayrithm
# Create .env from template
cp .env.example .env
Open .env in your editor and set:
# ── Gemini (free tier, default) ─────────────────────────
LLM_DEFAULT_PROVIDER=gemini
GEMINI_API_KEY=AIza...your-key... # https://aistudio.google.com/app/apikey
Get a free Gemini API key: Visit https://aistudio.google.com/app/apikey → Create API key: no credit card required.
Step 4: Start the stack
docker compose up --build -d
# Apply database migrations
docker compose exec backend uv run alembic upgrade head
| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API docs | http://localhost:8000/docs |
| Keycloak admin | http://localhost:8080 (admin / admin) |
| Qdrant dashboard | http://localhost:6333/dashboard |
| MinIO console | http://localhost:9001 (minioadmin / minioadmin) |
Keycloak first-start: Allow ~30 seconds after
docker compose upfor thenyayrithmrealm to be imported. The frontend login/register won’t work until this completes. Check progress withdocker compose logs keycloak.
Stopping and restarting
docker compose down # stop, keep data
docker compose down -v # stop + wipe volumes
docker compose up -d # restart
docker compose up --build -d # rebuild + restart
docker compose logs -f backend celery_worker # follow logs
Option B: Native (no Docker)
All services run natively on macOS. Best for development, faster hot-reload, no Docker overhead.
Step 1: Install Python 3.13
brew install python@3.13
# Add to PATH (Apple Silicon)
echo 'export PATH="/opt/homebrew/opt/python@3.13/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Verify:
python3.13 --version # Python 3.13.x
Step 2: Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
Close and reopen your terminal, then verify:
uv --version # uv 0.6+
Step 3: Install Node.js 24 LTS + Bun
brew install node@24
echo 'export PATH="/opt/homebrew/opt/node@24/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
curl -fsSL https://bun.sh/install | bash
Step 4: Install Redis
brew install redis
brew services start redis # starts Redis and enables auto-start on login
Verify:
redis-cli ping # PONG
Step 5: Clone and configure
git clone https://github.com/Aayush-Joshi-01/nyayrithm.git
cd nyayrithm
cp .env.example .env
Edit .env for native setup:
# ── LLM: Gemini (free tier) ──────────────────────────────
LLM_DEFAULT_PROVIDER=gemini
GEMINI_API_KEY=AIza...your-key...
# ── Embedder: local sentence-transformers ────────────────
EMBEDDER_BACKEND=sentence-transformers
EMBEDDING_DIMENSION=384
# ── DB: SQLite (no container needed) ─────────────────────
DB_BACKEND=sqlite
SQLITE_PATH=./nyayrithm.db
# ── Vector DB: Chroma (in-process, no container) ─────────
VECTOR_DB_BACKEND=chroma
CHROMA_HOST=localhost
CHROMA_PORT=8001
# ── Storage: local filesystem ────────────────────────────
STORAGE_BACKEND=local
STORAGE_LOCAL_ROOT=./storage
# ── Task queue: local Redis ──────────────────────────────
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/1
REDIS_URL=redis://localhost:6379/2
# ── Frontend ─────────────────────────────────────────────
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_WS_URL=ws://localhost:8000
Step 6: Install backend dependencies
cd backend
uv pip install -e ".[dev]"
Step 7: Install frontend dependencies
cd ../frontend
bun install
Step 8: Run (three terminal tabs)
Open three tabs in Terminal or iTerm2.
Tab 1, API server:
cd nyayrithm/backend
uv run uvicorn app.main:app --reload --port 8000
Tab 2, Celery worker:
cd nyayrithm/backend
uv run celery -A app.tasks.celery_app worker --loglevel=info -Q evidence,simulation,default
Tab 3, Frontend:
cd nyayrithm/frontend
bun dev
Native dev + Keycloak: Ensure
frontend/.env.localexists. Runmake envonce to create it. You still need Keycloak running, start it withdocker compose up keycloak -d.
Open http://localhost:3000.
Option C: Fully offline with Ollama
No internet required after initial model download.
Step 1: Install Ollama
brew install ollama
Or download directly from https://ollama.com/download (macOS .dmg app).
Step 2: Download models
ollama pull llama3.1:8b # ~4.7 GB, good balance of speed vs quality
ollama pull mistral-nemo # ~7.1 GB, alternative
# For Apple Silicon M2/M3/M4 Ultra with enough RAM:
# ollama pull llama3.1:70b # ~40 GB, best quality
Step 3: Start Ollama server
If you installed via Homebrew:
ollama serve
If you installed the macOS app, Ollama starts automatically and runs in the menu bar.
Verify:
curl http://localhost:11434/api/tags # lists downloaded models
Step 4: Configure .env
LLM_DEFAULT_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
EMBEDDER_BACKEND=sentence-transformers
EMBEDDING_DIMENSION=384
DB_BACKEND=sqlite
VECTOR_DB_BACKEND=chroma
STORAGE_BACKEND=local
Then follow Steps 6-8 from Option B.
Recommended Ollama models for Apple Silicon:
| Chip | Unified Memory | Recommended model |
|---|---|---|
| M1/M2 (base) | 8 GB | mistral-nemo, llama3.2:3b |
| M1/M2 Pro/Max | 16-32 GB | llama3.1:8b, gemma2:9b |
| M2/M3 Max/Ultra | 64-96 GB | llama3.1:70b |
| M4 Max/Ultra | 128 GB+ | llama3.1:70b (fast) |
Apple Silicon runs inference entirely on the Neural Engine + GPU, significantly faster than Intel Macs for local models.
Configuring LLM providers
Default: Gemini 2.5 Flash (free, recommended)
LLM_DEFAULT_PROVIDER=gemini
GEMINI_API_KEY=AIza...
Update backend/app/llm/registry.py:
ROLE_PROVIDER_MAP = {
"judge": ("gemini", "gemini-flash-lite-latest"),
"prosecutor": ("gemini", "gemini-flash-lite-latest"),
"defense": ("gemini", "gemini-flash-lite-latest"),
"plaintiff": ("gemini", "gemini-flash-lite-latest"), # lightest
"accused": ("gemini", "gemini-flash-lite-latest"),
"witness": ("gemini", "gemini-flash-lite-latest"),
"investigator": ("gemini", "gemini-flash-lite-latest"),
"expert_witness": ("gemini", "gemini-flash-lite-latest"),
"custom": ("gemini", "gemini-flash-lite-latest"),
}
⚠️ Gemini 2.0 Flash was deprecated. Use
gemini-flash-lite-latestorgemini-flash-lite-latestgoing forward.
Free tier quotas (May 2026):
| Model | RPD | Best for |
|---|---|---|
gemini-flash-lite-latest |
1,500 | Most roles, best reasoning on free tier |
gemini-flash-lite-latest |
1,500 | High-frequency simple roles |
gemini-2.5-pro |
50 | Judge only (very limited free quota) |
OpenAI
LLM_DEFAULT_PROVIDER=openai
OPENAI_API_KEY=sk-...
Anthropic
LLM_DEFAULT_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
Ollama (local)
LLM_DEFAULT_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
Mixing providers
# backend/app/llm/registry.py
ROLE_PROVIDER_MAP = {
"judge": ("anthropic", "claude-opus-4-5"),
"prosecutor": ("openai", "gpt-4o"),
"defense": ("openai", "gpt-4o"),
"plaintiff": ("gemini", "gemini-flash-lite-latest"), # free
"accused": ("gemini", "gemini-flash-lite-latest"), # free
"witness": ("ollama", "llama3.1:8b"), # local (Apple Silicon)
"investigator": ("openai", "gpt-4o-mini"),
"expert_witness": ("anthropic", "claude-sonnet-4-6"),
"custom": ("gemini", "gemini-flash-lite-latest"),
}
Verify the installation
# Check all services running
curl -s http://localhost:8000/health
# {"status": "ok", "version": "0.1.0"}
# Open docs in browser
open http://localhost:8000/docs
open http://localhost:3000
Run tests
cd backend
uv run pytest --cov=app --cov-report=term-missing -v
Run linters
# Backend
cd backend && uv run ruff check . && uv run mypy app/
# Frontend
cd frontend && bun run lint && bun run tsc --noEmit
Apple Silicon notes
Docker performance
Docker Desktop on Apple Silicon uses a lightweight Linux VM (Virtualization.framework). Performance is excellent, comparable to native speeds for most workloads.
If you encounter platform: linux/amd64 image compatibility warnings, add to docker-compose.yml:
services:
backend:
platform: linux/arm64 # prefer native ARM images
Most images (postgres, redis, qdrant) have native ARM64 builds.
Homebrew paths
On Apple Silicon, Homebrew installs to /opt/homebrew instead of /usr/local. If a tool is missing from PATH:
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Rosetta 2 (if needed)
Some older Python packages may require Rosetta 2 if they lack ARM64 wheels:
softwareupdate --install-rosetta --agree-to-license
This is rarely needed in 2026, most packages have ARM64 wheels.
faster-whisper on Apple Silicon
Audio transcription via faster-whisper uses CoreML acceleration on Apple Silicon automatically when ctranslate2 detects the chip. Transcription runs 3-5x faster than on Intel.
Troubleshooting
brew: command not found
Homebrew PATH not set. Add to ~/.zshrc (Apple Silicon):
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
source ~/.zshrc
Docker containers keep OOM-killing
Docker Desktop defaults to 50% of RAM. Increase in Docker Desktop → Settings → Resources → Memory. For the full stack (postgres + qdrant + minio + backend + frontend), allocate at least 6 GB.
Port 5432 already in use
You have a local PostgreSQL running. Either stop it or switch to SQLite:
brew services stop postgresql@16
# or:
DB_BACKEND=sqlite SQLITE_PATH=./nyayrithm.db
Redis Connection refused
brew services list | grep redis # check if running
brew services restart redis
redis-cli ping # should return PONG
ModuleNotFoundError on backend start
Virtual environment not activated or deps not installed:
cd backend
uv pip install -e ".[dev]"
uv run uvicorn app.main:app --reload --port 8000
Always prefix commands with uv run, it automatically activates the project’s virtual environment.
Celery workers not processing tasks
Check broker connectivity:
cd backend
uv run celery -A app.tasks.celery_app inspect active
If that fails, check Redis is up (redis-cli ping) and CELERY_BROKER_URL in .env is correct.
sentence-transformers slow on first run
~90 MB model downloaded on first embed_text() call. Cached at ~/.cache/huggingface/hub. Subsequent runs are instant.
Frontend EADDRINUSE: address already in use :::3000
Another process is on port 3000:
lsof -ti:3000 | xargs kill -9
bun dev
# or use a different port:
bun dev --port 3001
# update CORS_ORIGINS in .env to include http://localhost:3001