Redeo Docs
DocsLADR / Getting Started: Self-Host in 5 Minutes

Introduction

Getting Started: Self-Host in 5 Minutes

Getting Started: Self-Host in 5 Minutes

This guide gets a LADR stack running on your machine in under five minutes using Docker Compose. You will start the services, open Foundry in your browser, create your first ladder, and call it via curl.

Prerequisites

  • Docker and Docker Compose (v2+). Both are included in Docker Desktop.
  • An LLM provider API key (OpenAI, Anthropic, or any OpenAI-compatible provider).
  • Git to clone the repository.

No Go, Node.js, or other language toolchain is required. Everything runs inside containers.

Step 1: Clone and configure

bash
git clone https://github.com/redeolabs/ladr.git
cd ladr
cp .env.example .env

Edit .env and set your provider keys:

bash
# At minimum, set one provider key:
OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-ant-...

# Database (defaults work for Docker Compose):
DATABASE_URL=postgres://ladr:ladr@db:5432/ladr
REDIS_URL=redis://redis:6379

Step 2: Start the stack

bash
docker compose up -d

This starts seven services:

ServicePortPurpose
gateway8788OpenAI-compatible API. Entry point for all ladder calls.
api3001REST API for ladder CRUD, provider management.
engine3004Execution engine. Runs ladder steps.
worker3005Asynq worker. Processes engine jobs from the queue.
foundry3006Visual ladder editor. Browser-based.
postgres5432PostgreSQL database. Stores ladder configs, users, providers.
redis6379Redis. Pipeline state, event streams, job queue.

Verify all services are healthy:

bash
docker compose ps

Every service should show Up or healthy.

Step 3: Open Foundry and configure a provider

Open your browser to:

text
http://localhost:3006

Foundry is the visual editor where you author ladders. On first launch, you will create an account (stored locally in your PostgreSQL instance).

Configure a provider

Before you can run ladders, Foundry needs at least one LLM provider configured. Navigate to Settings, Providers where you have two options:

  1. Add a Custom Provider. Enter your own API key and (optionally) a custom base URL for any OpenAI-compatible provider (OpenAI, Anthropic, DeepInfra, Together, etc.). The key is stored encrypted in your local PostgreSQL database and used by the engine when dispatching LLM calls.

  2. Sign in with Redeo. If you have a Redeo account, signing in loads your connected providers from the Redeo platform. When connected:

    • Ladder execution routes through Redeo's servers (no local processing).
    • Your provider keys are used on the server side.
    • Only public ladders from the Redeo directory are visible. Private and closed ladders remain invisible — the self-hosted instance cannot access them.

For local-only operation, use Add a Custom Provider. The ladder engine runs entirely on your infrastructure using your own provider keys.

Generate an API key

Navigate to Settings, API Keys and create a key. Save it — you will use it in curl calls.

bash
export LADR_API_KEY="lk_..."

Step 4: Create and call your first ladder

In Foundry, click New Ladder. Paste this minimal config:

yaml
name: Echo
allowedTargets: { strategy: universal }
exit: answer
knobs: {}
steps:
  - id: answer
    name: Answer
    fields:
      - { name: Question, type: text, from: input.context }
    systemPrompt: "Answer the question concisely."

Click Save. The ladder is stored as local/echo (the local author namespace is used for self-hosted ladders).

Call it via curl

bash
curl http://localhost:8788/v1/local/echo/chat/completions \\
  -H "Authorization: Bearer $LADR_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "What is 2+2?"}]
  }'

The URL path encodes the ladder identity: /v1/{author}/{ladder-name}/. For self-hosted ladders, the author is local. The model field is the actual LLM model you want to use.

You will receive a standard OpenAI chat completion response:

json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "gpt-4o",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "4"
    },
    "finish_reason": "stop"
  }],
  "usage": { ... }
}

Step 5: Use any OpenAI client

Because the gateway is OpenAI-compatible, any existing OpenAI client works with a one-line base URL change:

Python (openai library):

python
from openai import OpenAI

client = OpenAI(
    api_key="lk_...",
    base_url="http://localhost:8788/v1/local/echo"
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What is 2+2?"}]
)
print(response.choices[0].message.content)

JavaScript (openai npm):

javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "lk-...",
  baseURL: "http://localhost:8788/v1/local/echo",
});

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "What is 2+2?" }],
});
console.log(response.choices[0].message.content);

Passing knobs:

Knobs are caller-tunable parameters declared in the ladder config. Pass them in the request body to control fan-out, recursion depth, and other strategy parameters at call time:

bash
curl http://localhost:8788/v1/local/draft-refine/chat/completions \\
  -H "Authorization: Bearer $LADR_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Design a REST API for a todo app."}],
    "knobs": { "branches": 5, "verifiers": 3 },
    "maxLoops": 3
  }'

Architecture overview

The request flow through the seven services:

text
Caller                Gateway(:8788)           Redis(Job Queue)
  │                       │                         │
  │ POST /v1/author/      │                         │
  │ ladder/chat           │                         │
  ├──────────────────────▶│                         │
  │                       │ enqueue job             │
  │                       ├────────────────────────▶│
  │                       │                         │
  │                       │              Worker(:3005)
  │                       │                  │
  │                       │                  │ dequeue
  │                       │                  ▼
  │                       │              Engine(:3004)
  │                       │                  │
  │                       │            ┌─────┼─────────┐
  │                       │            │     │         │
  │                       │            ▼     ▼         ▼
  │                       │         Redis   PostgreSQL  LLM Provider
  │                       │         (state) (configs)
  │                       │
  │         ◀─────────────┘  (exit step output → chat completion response)
  1. Caller sends POST /v1/{author}/{ladder}/chat/completions with model: "gpt-4o" and a messages array.
  2. Gateway authenticates via API key, resolves the ladder config from PostgreSQL, validates it, and creates a pipeline instance in Redis.
  3. Gateway enqueues an engine job.
  4. Worker picks up the job and calls the engine.
  5. Engine walks the steps, dispatches LLM calls via the configured provider, stores outputs in Redis, and publishes lifecycle events.
  6. On completion, the exit step's output is returned as the chat completion response.

Local execution (default). When you add a custom provider (your own API key), the engine runs on your infrastructure. The gateway receives the request, enqueues a job, the worker picks it up, and the engine dispatches LLM calls using your provider key. All processing is local.

Redeo-routed execution. When you sign in with Redeo, the platform can route execution through Redeo's servers instead of processing locally. Your provider keys (loaded from Redeo) are used server-side.

Troubleshooting

Services won't start. Check docker compose logs gateway for errors. The most common issue is a missing or invalid .env file.

404 on ladder call. Make sure you saved the ladder in Foundry and the URL path matches local/<ladder-name>. The name in the URL path must match the name: field in the ladder YAML, not the Foundry display name. The model field in the request body should be a valid LLM model name (e.g., gpt-4o), not the ladder name.

No LLM provider configured. Add a provider in Foundry under Settings, Providers. The engine needs at least one provider with a valid API key to dispatch LLM calls.

Port already in use. If ports 8788, 3001, 3004, 3005, or 3006 are already in use, edit docker-compose.yml to remap them.

Database not initialized. Run docker compose exec api /app/api --migrate to run database migrations manually.