Skip to content

Local Development Setup

Complete guide to running Martha locally from a fresh clone.


Prerequisites

  • Docker Desktop (with Compose v2)
  • Python 3.11+
  • Node 20+
  • Git

1. Clone and initialize submodules

bash
git clone git@github.com:westeuropeco/martha.git
cd martha
git submodule update --init --recursive

2. Start common infrastructure

Martha depends on shared services (PostgreSQL, Redis, Temporal, Keycloak) from the common-infra stack.

bash
cd common-infra
./setup.sh
cd ..

This creates the common-infra-network, starts all infrastructure services, and imports the Keycloak frank realm with test users.

Verify:

bash
docker exec postgres pg_isready -U postgres
docker exec redis redis-cli ping
curl -s http://localhost:8180/realms/frank/.well-known/openid-configuration | head -1

3. Configure environment

deployment/.env.dev contains dev-friendly defaults. You need to add API keys for LLM providers:

bash
# Edit and add your API keys
vim deployment/.env.dev

Required keys (at minimum one LLM provider):

KeyPurpose
ANTHROPIC_API_KEYClaude models
OPENAI_API_KEYOpenAI models

Optional keys are documented in the file.


4. Set up Keycloak client for Martha Admin

The admin panel requires an OAuth2 confidential client in Keycloak. This is automated:

bash
bash deployment/setup-dev-keycloak.sh

Copy the output AUTH_KEYCLOAK_SECRET=... value into deployment/.env.dev:

bash
echo 'AUTH_KEYCLOAK_SECRET=<paste-secret-here>' >> deployment/.env.dev

!!! note On a fresh Keycloak (clean DB), the client is auto-imported from frank-realm.json with a dev secret: martha-admin-dev-secret-change-in-prod. The script is for existing environments where the realm import was already applied without this client.


5. Start Martha services

bash
docker-compose -f deployment/docker-compose.dev.yml up -d

Services start in dependency order:

  1. martha-postgres-dev + martha-redis-dev (infrastructure)
  2. martha-api-dev (waits for postgres healthy)
  3. martha-worker-dev + martha-ingestion-worker-dev (wait for API healthy)
  4. martha-admin-svelte-dev + slo-pwa-dev (wait for API healthy)
  5. martha-rerank-dev (TEI cross-encoder reranker — see below)

Verify:

bash
docker-compose -f deployment/docker-compose.dev.yml ps
curl -s http://localhost:8080/health
curl -s http://localhost:8088/health  # rerank container (may take 30-60s on first start)

Reranker (#231 C2-3a)

The martha-rerank container runs Hugging Face TEI loaded with Alibaba-NLP/gte-multilingual-reranker-base. Recall calls TEI's /rerank endpoint to reorder hybrid-search candidates by cross-encoder score.

  • Add MARTHA_RERANKER_URL=http://martha-rerank-dev:80 to your local deployment/.env.dev so api/worker can reach the container. The variable is non-secret so it can be hardcoded in dev. (.env.dev is gitignored — each developer manages their own.)
  • First start downloads ~600MB from HF Hub (30-60s). Subsequent starts read from the rerank-model-cache named volume (~10-15s).
  • Healthcheck has start_period: 120s to absorb the cold-start window.
  • Fail-open contract: if the container is down or unreachable, recall returns merge-order results plus a structured WARN log. Never blocks chat.
  • Disable rerank for a session: unset MARTHA_RERANKER_URL in deployment/.env.dev and restart martha-api-dev + martha-worker-dev.
  • Swap the model: edit the command: in deployment/docker-compose.dev.yml and restart martha-rerank-dev. Common alternatives:
    • BAAI/bge-reranker-v2-m3 — XLM-RoBERTa, 568M, slightly higher quality multilingual at 2x cost.
    • Alibaba-NLP/gte-reranker-modernbert-base — ModernBERT, 149M, English-only, ~2x faster.
  • Verify rerank is firing: in the logs of martha-api-dev, look for memory.recall.rerank: success url=... candidates=... debug lines, or check the Prometheus counter martha_rerank_calls_total{outcome="success"}.

6. Run database migrations and seeds

Migrations run automatically on API startup. Seed scripts populate initial data:

bash
docker-compose -f deployment/docker-compose.dev.yml exec martha-api \
  python scripts/seed_platform_functions.py

docker-compose -f deployment/docker-compose.dev.yml exec martha-api \
  python scripts/seed_node_types.py

7. Access the applications

ApplicationURLAuth
Martha Adminhttp://localhost:5174Keycloak login (admin / admin123)
SLO PWAhttp://localhost:5173API key (preconfigured)
Martha APIhttp://localhost:8080JWT or API key
API Docshttp://localhost:8080/docsNone
Temporal UIhttp://localhost:8088None
Keycloak Consolehttp://localhost:8180admin / (from common-infra/.env)

Test users (Keycloak realm frank)

UsernamePasswordRolesTenant ID
adminadmin123admin, user550e8400-e29b-41d4-a716-446655440000
testusertestpassuser550e8400-e29b-41d4-a716-446655440001

Development workflow

Live reload

All services mount source code as volumes. Changes to Python files (API, core, services) trigger FastAPI auto-reload. Changes to Svelte files trigger Vite HMR.

Running tests

bash
# Python virtual env (for running tests outside Docker)
python -m venv myenv && source myenv/bin/activate
pip install -r requirements.txt

# Unit tests (no Docker needed)
pytest tests/unit/ -v

# Integration tests (needs Docker DB)
pytest tests/integration/ -v

# Frontend
cd martha-admin-svelte && npm run check && npm run build

Database access

bash
docker exec -it martha-postgres-dev psql -U martha -d martha

Logs

bash
# All services
docker-compose -f deployment/docker-compose.dev.yml logs -f

# Single service
docker-compose -f deployment/docker-compose.dev.yml logs -f martha-api

Teardown

bash
# Stop Martha services (preserves data)
docker-compose -f deployment/docker-compose.dev.yml down

# Stop everything including common-infra
docker-compose -f deployment/docker-compose.dev.yml down
cd common-infra && docker-compose down

# Nuclear option: remove all data
docker-compose -f deployment/docker-compose.dev.yml down -v
cd common-infra && docker-compose down -v

Troubleshooting

Martha Admin shows 500 Internal Error : Keycloak client not configured. Run bash deployment/setup-dev-keycloak.sh and add the secret to .env.dev.

Martha Admin shows "redirect_uri_mismatch" : Keycloak client redirect URIs don't include http://localhost:5174/*. Re-run the setup script.

API can't connect to Temporal : Ensure common-infra is running: docker exec temporal temporal operator cluster health

"common-infra-network not found" : Run cd common-infra && ./setup.sh first. The external network must exist before Martha services start.

Martha is built by aiaiai-pt.