Home
Softono
local-ai-toolkit

local-ai-toolkit

Open source MIT Go Template
16
Stars
2
Forks
0
Issues
0
Watchers
1 month
Last Commit

About local-ai-toolkit

A self-hosted AI toolkit running locally via Docker Compose, bundling an LLM gateway, workflow automation, and a chat UI — all backed by a shared PostgreSQL database.

Platforms

Web Self-hosted Docker

Languages

Go Template

Links

AI Local Toolkit

A self-hosted AI stack bundling an LLM gateway, workflow automation, and a chat UI — all backed by a shared PostgreSQL database. Deployable locally with Docker Compose or on any Kubernetes cluster via Helm.

LiteLLM ships with no models — register the providers you want in the LiteLLM admin UI, then use them from Open WebUI.

⚠️ Warning: This project is not production-ready out of the box. It has no TLS, no authentication proxy, no secrets management, and no backup strategy. It is safe for local use and trusted internal networks. See Production Checklist before exposing it to the internet or running it with real data.

Services

Service Description Docker Compose URL
LiteLLM OpenAI-compatible LLM API gateway http://localhost:4000
LiteLLM UI Admin dashboard http://localhost:4000/ui
n8n Visual workflow automation http://localhost:5678
Open WebUI ChatGPT-like interface http://localhost:3000

Architecture

┌─────────────┐              ┌─────────────┐
│  Open WebUI │              │     n8n     │
└──────┬──────┘              └──────┬──┬───┘
       │                            │  │
       │    OpenAI-compatible API   │  │ workflow storage
       └─────────────┬──────────────┘  │
                     ▼                 ▼
              ┌────────────┐    ┌────────────┐
              │  LiteLLM   │───▶│ PostgreSQL │
              └────────────┘    └────────────┘

Services communicate internally by container/pod name.

Open WebUI ↔ LiteLLM

Open WebUI is wired to LiteLLM over its OpenAI-compatible API. The stack injects only the host — never an API key. On first login, open the LiteLLM UI at http://localhost:4000/ui, create a virtual key, and paste it into Open WebUI under Settings → Connections. The LITELLM_MASTER_KEY is intentionally never given to Open WebUI — use a scoped virtual key instead.

Prerequisites

  • Docker Compose: Docker Engine + Docker Compose plugin
  • Kubernetes: a running cluster + Helm 3

Deployment

Option A — Docker Compose (local)

1. Create the shared network (one-time)

docker network create ai-toolkit

2. Configure environment

cp .env.dist .env

Edit .env:

POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<your_secure_password>

LITELLM_MASTER_KEY=sk-<generate_a_key>
LITELLM_SALT_KEY=sk-<generate_a_key>

TZ=America/New_York   # IANA timezone

3. Start the stack

docker compose up -d

4. Verify

docker compose ps   # wait until all services show "healthy"

Disabling services (optional)

Edit COMPOSE_PROFILES in .env to remove services you don't need:

# All enabled (default)
COMPOSE_PROFILES=litellm,n8n,openwebui

# Without n8n
COMPOSE_PROFILES=litellm,openwebui

# LiteLLM only (no UI, no automation)
COMPOSE_PROFILES=litellm

Postgres always runs — it is not profile-gated since other services depend on it. Disabling litellm requires also removing openwebui (it depends on LiteLLM).


Option B — Kubernetes / Helm

1. Install the chart

helm install ai-toolkit ./helm/ai-toolkit \
  --namespace ai-toolkit --create-namespace \
  --set litellm.masterKey=sk-... \
  --set litellm.saltKey=sk-... \
  --set postgresql.auth.password=...

For repeatable installs, use a values file instead of --set flags:

# my-values.yaml
litellm:
  masterKey: sk-...
  saltKey: sk-...

postgresql:
  auth:
    password: ...
helm install ai-toolkit ./helm/ai-toolkit \
  --namespace ai-toolkit --create-namespace \
  -f my-values.yaml

2. Access services (without Ingress)

kubectl port-forward svc/ai-toolkit-litellm 4000:4000
kubectl port-forward svc/ai-toolkit-n8n 5678:5678
kubectl port-forward svc/ai-toolkit-openwebui 3000:8080

3. Enable Ingress (optional)

Add to your values file:

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    litellm: litellm.example.com
    n8n: n8n.example.com
    openwebui: chat.example.com
  tls:
    - secretName: ai-toolkit-tls
      hosts:
        - litellm.example.com
        - n8n.example.com
        - chat.example.com

4. Use an external database (optional)

To disable the bundled PostgreSQL and point to your own (e.g. RDS, Cloud SQL):

postgresql:
  enabled: false

externalDatabase:
  host: my-db.example.com
  port: 5432
  username: postgres
  password: ...
  database: postgres

The external server must already have n8n and litellm databases created.

5. Disable individual services (optional)

n8n:
  enabled: false   # skip n8n if you don't need workflow automation

openwebui:
  enabled: false   # skip Open WebUI if you use a different frontend

Upgrade / uninstall

helm upgrade ai-toolkit ./helm/ai-toolkit -f my-values.yaml
helm uninstall ai-toolkit

Project Structure

.
├── docker-compose.yml            # Docker Compose stack definition
├── .env.dist                     # Environment variables template
├── config/
│   ├── litellm_config.yaml       # LiteLLM model registry (empty by default)
│   └── init_db.sh                # Creates n8n & litellm databases on first run
├── helm/
│   └── ai-toolkit/               # Helm chart for Kubernetes
│       ├── Chart.yaml
│       ├── values.yaml           # All chart defaults, fully annotated
│       └── templates/            # K8s manifests (Deployments, Services, PVCs, …)
└── .github/
    └── workflows/
        └── validate.yml          # CI: validates compose file and Helm chart

Models

LiteLLM ships with no models pre-configured — register the providers you want yourself. Any OpenAI-compatible or LiteLLM-supported provider works (OpenAI, Anthropic, Vertex, Groq, a local model server, …). See Adding models to LiteLLM below.


Configuration

Adding models to LiteLLM

LiteLLM ships with an empty model registry. Add models in config/litellm_config.yaml (Docker Compose) or via litellm.extraModels in your Helm values:

- model_name: gpt-4o
  litellm_params:
    model: openai/gpt-4o
    api_key: os.environ/OPENAI_API_KEY

Pair any provider key with litellm.extraEnv (Helm) or the litellm service environment (Docker Compose). You can also add models at runtime in the LiteLLM UI — STORE_MODEL_IN_DB persists them to Postgres.

Docker Compose: docker compose restart litellm Kubernetes: helm upgrade ai-toolkit ./helm/ai-toolkit -f my-values.yaml

Calling the LiteLLM API directly

curl http://localhost:4000/v1/models \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

PostgreSQL databases

A single PostgreSQL 16 instance hosts two databases: n8n and litellm. The config/init_db.sh script creates them on first startup and is idempotent (safe to re-run).

To reset the database (Docker Compose):

docker compose down
docker volume rm toolkit_postgres-data
docker compose up -d

Docker Compose — Useful Commands

docker compose up -d                    # start all services
docker compose down                     # stop all services
docker compose ps                       # show service health
docker compose logs -f litellm          # tail logs for one service
docker compose restart litellm          # reload after config change
docker compose down -v && docker compose up -d  # full reset (deletes data)

Troubleshooting

docker compose up fails with "network ai-toolkit not found"

docker network create ai-toolkit

Services stay starting or unhealthy LiteLLM and n8n wait for Postgres to pass its healthcheck before starting. On first run, Postgres runs the init script which can take 20–30 s. Check progress:

docker compose logs -f postgres

Open WebUI shows no models Open WebUI ships with the LiteLLM host wired in but no API key — add a LiteLLM virtual key (from http://localhost:4000/ui) under Settings → Connections. LiteLLM itself serves no models until you register them (see Adding models to LiteLLM above):

docker compose logs -f litellm

n8n can't connect to the database The POSTGRES_USER and POSTGRES_PASSWORD in .env must match what was used when the postgres-data volume was first created. If they changed, reset the volume or revert the credentials.

Port already in use Change the host-side port in docker-compose.yml, e.g. "4001:4000" for LiteLLM.

Helm pod stuck in Pending The cluster likely has no default StorageClass for PVCs. Either install one or set persistence.storageClass in your values to an available class:

kubectl get storageclass

Production Checklist

This stack ships with sane defaults for development and internal use. The items below are required before running it with real users or sensitive data.

Must-have

Item How
TLS Add cert-manager to your cluster and set ingress.annotations with a ClusterIssuer. All traffic is plain HTTP by default.
Authentication proxy Put oauth2-proxy or Authelia in front of every public-facing service. None of the services (LiteLLM UI, n8n, Open WebUI) require login by default.
Secrets management .env files and K8s Secrets store credentials in plaintext / base64. Use External Secrets Operator with AWS Secrets Manager, GCP Secret Manager, or Vault to inject secrets at runtime.
PostgreSQL backups Deploy a pg_dump CronJob or use Velero for volume snapshots. There is no backup strategy included. Data loss = permanent loss of n8n workflows and LiteLLM audit logs.
Pin image tags main-stable, latest, and main are mutable — a re-pull can silently introduce a breaking change. Pin to a specific version in values.yaml (e.g. tag: "v1.45.0") for reproducible deployments.

Should-have

Item How
n8n secure cookies N8N_SECURE_COOKIE=false is forced because there is no HTTPS by default. Once TLS is in place, remove that override from n8n-deployment.yaml.
Network policies By default every pod can reach every other pod. Add Kubernetes NetworkPolicy resources to restrict postgres and litellm to only their direct consumers.
Resource tuning The default resource limits in values.yaml are starting points. Profile your actual workload and adjust — especially PostgreSQL memory if you have large n8n execution history.
Monitoring Add Prometheus + Grafana to the cluster. LiteLLM exposes Prometheus metrics at /metrics.