Skip to main content

Local development setup

Last Updated: 2026-05-23 Status: Alpha This is the end-to-end walkthrough for getting Poindexter running on your own machine. If you only want “one command to a working pipeline,” run poindexter setup --auto — read Quick Start in the README first. This document covers the longer form: what the setup wizard does under the hood, how to verify each layer, and how to troubleshoot when something doesn’t come up.

Minimum hardware

TierGPU VRAMWhat it unlocks
Minimum8 GBRuns smaller Ollama models only; writer model will be constrained to 7B range
Recommended16 GBSupports Q4 quantized 7B–14B models at full quality
Optimal24 GB+Q4_K_M 32B writer models; comfortable headroom for image-gen + Ollama simultaneously
CPU-onlyno GPUFallback available via pipeline_writer_model=ollama/gemma2:2b-instruct-q4_K_M but output quality will be noticeably poor
RAM: 32 GB minimum, 64 GB recommended (the full stack including Langfuse, ClickHouse, and Grafana uses 8–12 GB resident at idle). Disk: 100 GB free for model weights, Docker images, and generated media.

1. Prerequisites

ToolVersionPurposeRequired?
Docker20.10+Runs the entire backend stackYes
Ollama0.1.40+Local LLM inferenceYes
Node.js22+Frontend (Next.js) and lint-staged hooksYes
Git + Git Bashanystart-stack.sh uses bashYes
Python3.13+CLI + running worker outside DockerYes
GPU8GB VRAMOllama inference is far faster with CUDARecommended
Windows note. Run all commands from Git Bash or WSL. Native cmd.exe and PowerShell do not work with the start scripts. Docker Desktop must be configured to use WSL2 backend. Linux note. Stock Docker Engine on Linux does not automatically resolve host.docker.internal — this is a Docker Desktop feature. The compose files add extra_hosts: ["host.docker.internal:host-gateway"] to every service that calls a host-side endpoint (Ollama, image-gen, voice bridge). host-gateway is a Docker built-in alias that resolves to the host’s IP and is supported on Docker Engine 20.10+. No manual configuration is needed; the extra_hosts entries are already present in both docker-compose.yml and docker-compose.local.yml. GPU note. You can run Poindexter on CPU, but content generation that takes 30 seconds on an RTX 4090 can take 10+ minutes on CPU. Not practical for daily use.

2. Clone and setup

The setup wizard does the following:
  1. Prompts for a database URL (or auto-provisions a local Docker Postgres with --auto).
  2. Tests the database connection and reports success/failure.
  3. Runs migrations against the target database. Safe to re-run — migrations are idempotent.
  4. Generates secrets — creates random local_postgres_password, grafana_password, and pgadmin_password.
  5. Writes ~/.poindexter/bootstrap.toml with the database URL + generated secrets. This is the only config file on disk.
  6. Provisions the initial CLI OAuth client — registers a row in oauth_clients, encrypts the credentials into app_settings.cli_oauth_client_id / cli_oauth_client_secret, and prints the plaintext secret once for capture. (Worker auth uses OAuth 2.1 only as of Glad-Labs/poindexter#249.)
No .env file is created. All secrets live in bootstrap.toml (safe permissions, never committed to git).

3. Pull AI models

Total first-run download: ~21GB. For better writing quality, also pull a larger writer model:

4. Bring up the full stack

This reads ~/.poindexter/bootstrap.toml, exports the values as env vars, and runs docker compose -f docker-compose.local.yml up -d. No .env file needed. This starts the core containers (cross-referenced against the CLAUDE.md Quick-Links table for ports + purposes):
ContainerPurposePort
poindexter-workerFastAPI backend, content pipeline8002
poindexter-brain-daemonHealth probes + self-healing loop
poindexter-postgres-localPostgreSQL 16 + pgvector5433
poindexter-grafanaMonitoring dashboards3000
poindexter-prometheusMetric scraper9091
poindexter-image-gen-serverimage-gen image generation (GPU)9836
poindexter-pgadminDatabase GUI18443
poindexter-langfuseLLM trace explorer + prompt UI (UnifiedPromptManager edits land here)3010
poindexter-glitchtipSelf-hosted Sentry — runtime errors from worker / brain / voice agent8080
poindexter-prefectOrchestration UI for the Prefect server (flow runs, schedules)4200
poindexter-pyroscopeContinuous profiler — flame graphs from worker / brain / voice4040
poindexter-lokiLog storage (consumed via Grafana Explore — Loki datasource)3100
poindexter-tempoTrace storage (consumed via Grafana Explore — Tempo datasource)3200
poindexter-alertmanagerAlert-routing UI9093
poindexter-livekitLocal LiveKit server (Tailscale Serve fronts /voice/join, tailnet-only)7880
Stop optional containers if you don’t need them:

5. Verify

The task should move through pending → in_progress → awaiting_approval within a few minutes. Follow along via:

6. Frontend (optional for backend dev)

If you’re only iterating on the backend, skip the frontend — the worker’s API and the Grafana dashboards are all you need. If you do want the Next.js public site running locally:
Open http://localhost:3000.

7. Run the tests

The unit suite runs lean — the cross-encoder reranker (sentence-transformers
  • torch) is an opt-in rerank extra that CI deliberately skips, and the tests that touch it importorskip. Add poetry install --extras rerank only if you want to exercise the reranker locally.
Expected: the full unit suite passes (several thousand cases). Some tests that depend on the brain module or sentry-sdk are skipped when running inside Docker (these pass on the host where all modules are available).

8. What to do when something breaks

See troubleshooting.md.

Configuration

All runtime configuration lives in the app_settings Postgres table, not env vars. After setup, change settings with:
See environment-variables.md for the bootstrap-layer reference (the few env vars Docker still needs), and reference/app-settings.md for the full DB-layer settings catalog.