Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@ export PYTHONUNBUFFERED=1
export OAUTH2_ACTIVE=0
export LOG_LEVEL=DEBUG
export WEBSOCKET_BROADCASTER_URL="redis://localhost:6379"

export OPENAI_API_KEY=None
export AGENT_ENABLED=False
export SEARCH_ENABLED=False
# export COMPOSE_PROFILES=lso # unhash the start of this line to also start up lso container
29 changes: 27 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ x-netbox: &netbox
services:
postgres:
container_name: postgres
image: "postgres:17-alpine"
image: "pgvector/pgvector:pg17"
ports:
- "5432:5432"
environment:
Expand Down Expand Up @@ -71,6 +71,25 @@ services:
volumes:
- netbox-redis-cache-data:/data

embeddings:
container_name: embeddings
image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.8
command: --model-id sentence-transformers/all-MiniLM-L6-v2
profiles:
- embeddings
env_file:
- ./docker/embeddings/embeddings.env
- path: ./docker/overrides/embeddings/embeddings.env
required: false
ports:
- "8081:80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s

rover-compose:
container_name: rover-compose
build:
Expand Down Expand Up @@ -160,10 +179,13 @@ services:
image: ${ORCH_BACKEND_TAG:-ghcr.io/workfloworchestrator/orchestrator-core:latest}
env_file:
- ./docker/orchestrator/orchestrator.env
- ./docker/embeddings/embeddings.env
- path: ./docker/overrides/orchestrator/orchestrator.env
required: false
environment:
LSO_ENABLED: ${COMPOSE_PROFILES:+True}
AGENT_ENABLED: ${AGENT_ENABLED:-False}
SEARCH_ENABLED: ${SEARCH_ENABLED:-False}
ports:
- "8080:8080"
- "5678:5678" #Enable Python debugger
Expand All @@ -179,7 +201,7 @@ services:
- ./graphql_federation.py:/home/orchestrator/graphql_federation.py
- ./utils:/home/orchestrator/utils
- ./services:/home/orchestrator/services
- ./requirements.txt:/home/orchestrator/requirements.txt
- ./pyproject.toml:/home/orchestrator/pyproject.toml
- ./alembic.ini:/home/orchestrator/alembic.ini
- ./translations:/home/orchestrator/translations
- ./templates:/home/orchestrator/templates
Expand All @@ -191,6 +213,9 @@ services:
condition: service_healthy
redis:
condition: service_healthy
embeddings:
condition: service_healthy
required: false
healthcheck:
start_period: 15s
timeout: 5s
Expand Down
88 changes: 88 additions & 0 deletions docker/embeddings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Embeddings Service

This directory configures a local embedding server using Hugging Face Text Embeddings Inference (TEI) with the `sentence-transformers/all-MiniLM-L6-v2` model.

## Overview

The embeddings service provides an OpenAI-compatible API for generating text embeddings locally.

- **Model**: sentence-transformers/all-MiniLM-L6-v2
- **Embedding Dimension**: 384
- **API Endpoint**: http://embeddings:80/v1 (internal), http://localhost:8081/v1 (external)

## Prerequisites

To use embeddings for search and agent features, add these to your `.env` file (see `.env.example`):

```env
AGENT_ENABLED=True
SEARCH_ENABLED=True
OPENAI_API_KEY=your-api-key-here # Optional: only needed for agent features or when using OpenAI embeddings
```

## Local Embeddings (Default)

This setup uses a local embedding service with no external API required. The default configuration in `embeddings.env` is:

- `OPENAI_BASE_URL=http://embeddings:80/v1`
- `EMBEDDING_DIMENSION=384`

### Start the orchestrator

Start the orchestrator with the local embeddings service:

```bash
docker compose --profile embeddings up orchestrator
```

## Alternative: Using OpenAI Embeddings

If you prefer to use OpenAI's embedding service instead of running a local model:

### Configuration

Override the embedding settings by editing `docker/overrides/embeddings/embeddings.env`:

```env
OPENAI_BASE_URL=https://api.openai.com/v1
EMBEDDING_DIMENSION=1536
```

### Start the orchestrator

Start only the orchestrator (skips the local embeddings service):

```bash
docker compose up orchestrator
```

## Post-Setup Steps

After starting the services and making sure you have data for the entity you want to index:

### 1. Apply the schema change

This will resize the vector dimension to match your embedding configuration (384 for local, 1536 for OpenAI) and delete existing records:

```bash
docker compose exec orchestrator /home/orchestrator/.venv/bin/python main.py embedding resize
```

⚠️ **Note**: This command will delete all existing embedding records.

### 2. Re-index your data

Example Index subscriptions:

```bash
docker compose exec orchestrator /home/orchestrator/.venv/bin/python main.py index subscriptions
```

## Advanced Configuration

The following configurations use conservative defaults for local/unknown models:

- `EMBEDDING_FALLBACK_MAX_TOKENS=512`: Maximum tokens per embedding request
- `EMBEDDING_MAX_BATCH_SIZE=32`: Maximum batch size for embedding requests

**Note**: These settings are only used as fallbacks for local or unknown models (like the example in this setup). For known providers and models, the system automatically retrieves the correct values via LiteLLM. The fallback values are already configured safely for local models, but can be adjusted if needed in `docker/overrides/embeddings/embeddings.env`.
11 changes: 11 additions & 0 deletions docker/embeddings/embeddings.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Default: Local embeddings service using sentence-transformers/all-MiniLM-L6-v2
# Provides OpenAI-compatible embeddings API locally with no external dependencies

OPENAI_BASE_URL=http://embeddings:80/v1
EMBEDDING_DIMENSION=384
EMBEDDING_MAX_BATCH_SIZE=32 # Not required when using OpenAI

# Alternative: Uncomment below to use OpenAI embeddings instead
# (Requires OPENAI_API_KEY in your .env file)
# OPENAI_BASE_URL=https://api.openai.com/v1
# EMBEDDING_DIMENSION=1536
32 changes: 26 additions & 6 deletions docker/orchestrator/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,40 @@
PATH=$PATH:~/.local/bin

# Install extra requirements for orchestrator
pip install -r requirements.txt
pip install uv
uv sync
source .venv/bin/activate

if [ -f ${CORE_OVERRIDE}/pyproject.toml ]; then
echo "⏭️ Use editable install of orchestrator-core with dev and test dependencies"
pip install -e $CORE_OVERRIDE[dev,test]
echo "⏭️ Use editable install of orchestrator-core"

extras=""
[ "${AGENT_ENABLED,,}" = "true" ] && extras+="agent,"
[ "${SEARCH_ENABLED,,}" = "true" ] && extras+="search,"

install_spec="$CORE_OVERRIDE"
if [ -n "$extras" ]; then
# Example: '/path/to/core[agent,search]'
install_spec="$CORE_OVERRIDE"'['"${extras%,}"']'
fi

echo "Installing with spec: '$install_spec'"
uv pip install -e "$install_spec"

# Run any missing migrations on the database
python main.py db upgrade heads

uvicorn --host 0.0.0.0 --port 8080 $UVICORN_ARGS main:app --reload --proxy-headers --reload-dir $CORE_OVERRIDE
uvicorn --host 0.0.0.0 --port 8080 $UVICORN_ARGS main:app --reload --proxy-headers \
--reload-dir $CORE_OVERRIDE \
--reload-dir products \
--reload-dir services \
--reload-dir translations \
--reload-dir utils \
--reload-dir workflows
else
# Run any missing migrations on the database
python main.py db upgrade heads

echo "⏭️ Use pip installed orchestrator-core $(pip freeze | grep orchestrator-core)"
echo "⏭️ Use orchestrator-core as specified in pyproject.toml $(uv pip freeze | grep orchestrator-core)"
uvicorn --host 0.0.0.0 --port 8080 $UVICORN_ARGS main:app --reload --proxy-headers
fi
fi