lisa
CLAUDE.md85 starsChanged 21 months agoApache-2.0View on GitHub
Self-hosted AI platform combining N8N automation, Supabase database, Ollama LLMs, Whisper speech recognition, and media processing in a unified Docker Compose stack. The project uses a unified Docker Compose architecture with two separate compose files merged under one project: Critical: Never use separate project names. All docker compose commands MUST use -p localai to maintain service connectivity. Ollama uses Docker Compose profiles to support different hardware: Each profile has a matching init container (ollama-pull-models) that auto-downloads gemma3:1b (компактная модель от…
- Reads credentials
We split this CLAUDE.md into the rules it gives an agent
13 rules. About 0 are common, 1 is distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 24
Critical: Never use separate project names.
- Very specific: line 71
Create timestamped backup tarball (.env, n8n/backup, neo4j/data, shared/)
- Very specific: line 72
Stop all services with docker compose -p localai down
- Very specific: line 93
Create shared/ directory with mode 777
- Very specific: line 95
Stop existing containers: docker compose -p localai down
- Very specific: line 96
Start Supabase stack: docker compose -p localai -f supabase/docker/docker-compose.yml up -d
- Distinctive: line 97
Wait 30 seconds for Supabase initialization
- Very specific: line 98
Start AI stack: docker compose -p localai --profile <profile> -f docker-compose.yml [-f docker-compose.override.<env>.yml] up -d
- Very specific: line 99
Wait for PostgreSQL healthcheck to become healthy (max 120s)
- Very specific: line 255
If N8N_HOSTNAME=n8n.example.com → HTTPS with Let's Encrypt cert
- Very specific: line 256
If N8N_HOSTNAME=:8001 → HTTP on localhost:8001
- Very specific: line 344
Check Caddy logs: docker logs caddy -f
- Very specific: line 351
Use base model instead of medium/large on CPU
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Л.И.С.А. — Локальная Интеллектуальная Система Автоматизации
Self-hosted AI platform combining N8N automation, Supabase database, Ollama LLMs, Whisper speech recognition, and media processing in a unified Docker Compose stack.
Core Architecture
Multi-Compose Stack Pattern
The project uses a unified Docker Compose architecture with two separate compose files merged under one project:
- Main stack (
docker-compose.yml) — AI services (N8N, Ollama, Whisper, Qdrant, etc.) - Supabase stack (
supabase/docker/docker-compose.yml) — Full Supabase suite included viainclude:directive - All services share:
- Single Docker network:
localai_default - Single project name:
localai - Single
.envfile (copied tosupabase/docker/.envby startup script)
- Single Docker network:
Critical: Never use separate project names. All docker compose commands MUST use -p localai to maintain service connectivity.
GPU Profile System
Ollama uses Docker Compose profiles to support different hardware:
cpu→ollama-cpuservice (no GPU acceleration)gpu-nvidia→ollama-gpuservice with NVIDIA device reservationsgpu-amd→ollama-gpu-amdservice with ROCm image and/dev/kfd,/dev/dridevices
Each profile has a matching init container (ollama-pull-models) that auto-downloads gemma3:1b (компактная модель от Google, ~1GB) and nomic-embed-text models on first run.
Custom N8N Build
N8N uses a custom Dockerfile (n8n-ffmpeg/Dockerfile) that adds FFmpeg to the official image:
- Base:
n8nio/n8n:latest - Adds: FFmpeg + ffprobe via
apk add - Purpose: Enable media processing in N8N Execute Command nodes
Important: This image must be rebuilt when N8N updates. Use docker compose -p localai build n8n to rebuild.
Development Commands
Installation
# First-time setup (interactive)
python3 CTAPT.pyThis script:
- Detects GPU (NVIDIA/AMD/CPU)
- Validates domains and email for Let's Encrypt
- Generates all secrets (N8N encryption keys, Supabase JWT, database passwords)
- Creates
.envfile with configuration - Configures UFW firewall (ports 22, 80, 443) — CRITICAL: SSH rule added BEFORE enabling firewall
- Calls
start_services.pyto launch stack
Update System
# Update to latest version
python3 O6HOBA.pyUpdate process:
- Detect current GPU profile and environment from
.env - Create timestamped backup tarball (
.env,n8n/backup,neo4j/data,shared/) - Stop all services with
docker compose -p localai down - Pull Git updates from
mainbranch - Calculate and update resource limits in
.envbased on detected CPU/RAM - Pull new Docker images with
docker compose pull --ignore-buildable - Rebuild custom images (
n8n-ffmpeg) - Restart services via
start_services.py
Manual Service Control
# Start with specific profile and environment
python3 start_services.py --profile cpu --environment public
# Options:
# --profile: cpu | gpu-nvidia | gpu-amd | none
# --environment: private | publicStartup sequence (start_services.py):
- Validate
.envhas required variables (POSTGRES_PASSWORD,N8N_ENCRYPTION_KEY,JWT_SECRET,N8N_RUNNERS_AUTH_TOKEN) - Clone Supabase repo with sparse checkout (only
docker/directory) if missing - Create
shared/directory with mode 777 - Copy
.env→supabase/docker/.env - Stop existing containers:
docker compose -p localai down - Start Supabase stack:
docker compose -p localai -f supabase/docker/docker-compose.yml up -d - Wait 30 seconds for Supabase initialization
- Start AI stack:
docker compose -p localai --profile <profile> -f docker-compose.yml [-f docker-compose.override.<env>.yml] up -d - Wait for PostgreSQL healthcheck to become
healthy(max 120s)
Docker Compose Commands
# View all running containers
docker ps
# Logs for entire project
docker compose -p localai logs -f
# Logs for specific service
docker logs n8n -f
docker logs whisper -f
docker logs ollama -f
# Stop all services (preserves volumes/data)
docker compose -p localai down
# Stop and DELETE all data (destructive!)
docker compose -p localai down -v
# Rebuild specific service
docker compose -p localai build n8n
docker compose -p localai up -d n8n
# Resource monitoring
docker stats
# Important: ALWAYS use -p localai to target the correct projectImplementation Details
Environment Configuration
The .env file is generated by CTAPT.py and contains:
Generated secrets (via secrets module):
N8N_ENCRYPTION_KEY,N8N_USER_MANAGEMENT_JWT_SECRET(32-byte hex)N8N_RUNNERS_AUTH_TOKEN(32-byte hex) — токен для Task Runners External ModePOSTGRES_PASSWORD,DASHBOARD_PASSWORD(alphanumeric only, no special chars to avoid URL encoding issues)SECRET_KEY_BASE,VAULT_ENC_KEY(for Supabase)LOGFLARE_PUBLIC_ACCESS_TOKEN,LOGFLARE_PRIVATE_ACCESS_TOKEN
User-provided values:
JWT_SECRET,ANON_KEY,SERVICE_ROLE_KEY— Supabase auth keys (generate at https://supabase.com/docs/guides/self-hosting/docker#generate-and-configure-api-keys)N8N_HOSTNAME,SUPABASE_HOSTNAME— Domains for HTTPS accessLETSENCRYPT_EMAIL— Must be real email, Let's Encrypt rejects fake addresses liketest@test.test
Resource limits (auto-calculated by O6HOBA.py and start_services.py):
- Format:
{SERVICE}_CPU_LIMIT,{SERVICE}_MEM_LIMIT,{SERVICE}_CPU_RESERVE,{SERVICE}_MEM_RESERVE N8N_HEAP_SIZE— Node.js heap size (75% от N8N_MEM_LIMIT), критично для предотвращения OOM- Allocation optimized for RAG workflows: Ollama 30%, N8N 22%, PostgreSQL 18%, Runners 8%, Qdrant 5%
- Limits are recalculated on every update via
O6HOBA.pyto apply optimizations
Proxy settings (optional, for routing API requests via external proxy):
PROXY_ENABLED=true/false— Enable/disable Squid proxyPROXY_IP,PROXY_PORT,PROXY_USER,PROXY_PASS— External proxy credentials
Squid Proxy Configuration
Optional proxy service for routing API requests (Anthropic, OpenAI, OpenRouter) through an external proxy. Useful for regions with API restrictions.
Input format during setup:
IP:PORT@USER:PASSExample: 45.87.241.81:8000@eoJaVV:fs4nPg
Enter - to skip proxy configuration.
Architecture:
┌─────────┐ HTTP_PROXY ┌─────────┐ cache_peer ┌──────────────┐
│ n8n │──────────────►│ squid │──────────────►│ External │
│ │ │ :3128 │ │ Proxy Server │
└─────────┘ └─────────┘ └──────────────┘Routed domains:
.anthropic.com,.claude.ai— Anthropic/Claude API.openai.com,.api.openai.com— OpenAI API.openrouter.ai— OpenRouter API.x.ai,api.x.ai— Grok (xAI) API.googleapis.com,generativelanguage.googleapis.com— Google Gemini API
Files:
squid/squid.conf.template— Template with placeholderssquid/squid.conf— Generated config (auto-created from template)
Docker Compose profile: proxy — Squid service only starts when PROXY_ENABLED=true
Managing proxy:
- During installation:
CTAPT.pyprompts for proxy input - During updates:
O6HOBA.pyallows changing/disabling proxy - Squid config is regenerated automatically when proxy settings change
Supabase Sparse Checkout
Supabase is cloned with Git sparse checkout to download only the docker/ directory (~200MB instead of 2GB):
git clone --filter=blob:none --no-checkout https://github.com/supabase/supabase.git
cd supabase
git sparse-checkout init --cone
git sparse-checkout set docker
git checkout masterThe main compose file includes it via:
include:
- ./supabase/docker/docker-compose.ymlN8N Auto-Import Pattern
N8N workflows/credentials are imported on first launch using a one-shot init container:
n8n-import:
container_name: n8n-import
entrypoint: /bin/sh
command:
- "-c"
- "n8n import:credentials --separate --input=/backup/credentials && n8n import:workflow --separate --input=/backup/workflows"
volumes:
- ./n8n/backup:/backup
n8n:
depends_on:
n8n-import:
condition: service_completed_successfullyThe main N8N container waits for successful import completion before starting.
Shared Directory
The shared/ directory enables file exchange between containers:
- N8N mounts it as
/data/shared - Used for temporary media files during FFmpeg processing
- Must have mode 777 for write access from all containers
- Auto-created by
CTAPT.pyandstart_services.py
Caddy Dual-Mode Routing
Caddy supports simultaneous domain and localhost access via environment variable syntax:
{$N8N_HOSTNAME}, :8001 {
reverse_proxy n8n:5678
}- If
N8N_HOSTNAME=n8n.example.com→ HTTPS with Let's Encrypt cert - If
N8N_HOSTNAME=:8001→ HTTP on localhost:8001 - Both modes can coexist by listing both (domain AND port)
Service Internal URLs
Whisper (OpenAI-compatible speech-to-text):
- URL:
http://whisper:8000 - Endpoint:
POST /v1/audio/transcriptions - Body:
multipart/form-datawithfile(binary) andmodel(tiny/base/small) - Recommended:
basemodel for CPU (best speed/accuracy balance)
Other key services:
- Ollama:
http://ollama:11434 - Qdrant:
http://qdrant:6333 - Supabase API:
http://kong:8000(via Kong gateway) - PostgreSQL (N8N):
postgres:5432 - PostgreSQL (Supabase):
db:5432 - N8N Task Broker:
n8n:5679(для подключения runners)
PostgreSQL Healthcheck Wait
start_services.py waits for PostgreSQL healthcheck before completing:
def wait_for_postgres_healthy(timeout=120):
result = subprocess.run(
["docker", "inspect", "--format", "{{.State.Health.Status}}", "localai-postgres-1"],
capture_output=True, text=True
)
return result.stdout.strip() == "healthy"This prevents N8N connection failures during parallel startup.
Pre-built N8N Workflows
Located in n8n/backup/workflows/, auto-imported on first launch:
- RAG L.I.S.A.json — Production-ready RAG система с автозагрузкой файлов:
- File trigger на
/data/shared— автоматическая индексация новых файлов - Поддержка CSV, Excel, TXT, PDF
- pgvector для векторного поиска, SQL для табличных данных
- Оптимизированные настройки:
chunkSize=1000,chunkOverlap=100
- File trigger на
- Telegram Bot.json — Full-featured bot with voice transcription, image analysis, analytics commands
- HTTP Handle.json — Webhook configuration helper
- Конвертация WebM → OGG + Транскрибация.json — Media conversion with Whisper transcription
- V1_Local_RAG_AI_Agent.json — Basic RAG with Ollama
- V2_Local_Supabase_RAG_AI_Agent.json — RAG with Supabase vector store (pgvector)
- V3_Local_Agentic_RAG_AI_Agent.json — Advanced agentic RAG
Common Issues
FFmpeg not found in N8N
Problem: ffmpeg: not found in Execute Command node
Solution: Rebuild the custom N8N image:
docker inspect n8n | grep n8n-ffmpeg # Verify custom image is in use
docker compose -p localai build n8n
docker compose -p localai up -d n8nPostgreSQL unhealthy
Problem: container localai-postgres-1 is unhealthy
Solution:
docker logs localai-postgres-1 # Check logs
grep POSTGRES_VERSION .env # Verify version is 16
docker compose -p localai down -v && python3 CTAPT.py # Nuclear option: wipe and reinstallPermission denied in shared/
Problem: N8N cannot write to /data/shared
Solution: chmod 777 shared/ (auto-fixed by start_services.py)
HTTPS not working
Problem: ERR_SSL_PROTOCOL_ERROR on domain access
Checklist:
.envhas real email (nottest@test.test)- DNS A-records point to server IP
- Ports 80/443 open in firewall
- Check Caddy logs:
docker logs caddy -f
Whisper crashes on large files
Problem: socket hang up or ECONNRESET during transcription
Solutions:
- Use
basemodel instead ofmedium/largeon CPU - Split files into <25MB chunks
- Increase container memory limits
Task Runners — External Mode (n8n 2.0+)
Начиная с n8n 2.0, Code ноды выполняются через Task Runners — отдельные процессы для изоляции и безопасности. Л.И.С.А. использует External Mode — рекомендуемый подход для production.
Архитектура:
┌─────────────┐ WebSocket ┌──────────────┐
│ n8n │◄──────:5679────────►│ n8n-runners │
│ (broker) │ AUTH_TOKEN │ (JS+Python) │
└─────────────┘ └──────────────┘Поддерживаемые языки:
- JavaScript — полная поддержка, встроенные модули
- Python — native Python (не Pyodide), включён через
N8N_NATIVE_PYTHON_RUNNER=true
Ключевые переменные:
N8N_RUNNERS_AUTH_TOKEN— секретный токен для связи n8n и runners (генерируется автоматически)N8N_RUNNERS_MODE=external— использование отдельного контейнераN8N_NATIVE_PYTHON_RUNNER=true— включение поддержки Python Code нодN8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0— брокер слушает на всех интерфейсах
Лимиты памяти для 8GB RAM (оптимизировано для RAG):
| Сервис | RAM | CPU | Heap | Назначение |
| Ollama | 2.5GB | 50% | — | LLM + embedding модели |
| N8N | 1.8GB | 30% | 1.3GB | Workflow engine, обработка файлов |
| PostgreSQL | 1.5GB | 25% | — | Supabase + pgvector |
| N8N Runners | 640MB | 15% | — | Code ноды (JS/Python) |
| Qdrant | 400MB | 10% | — | Векторы (резерв) |
ВАЖНО: N8N_HEAP_SIZE должен быть ~75% от N8N_MEM_LIMIT. Если heap > limit контейнера, Docker убьёт процесс по OOM.
Проверка работы:
# Проверить что runners подключился
docker logs n8n 2>&1 | grep -i "runner"
# Должно быть: "Task broker ready" или "Runner connected"
# Проверить статус контейнера runners
docker ps | grep n8n-runnersRAG workflow падает при загрузке больших файлов
Problem: N8N или Ollama падает при загрузке документов в RAG L.I.S.A.
Причины и решения:
- N8N OOM (Out of Memory):
- Проверьте логи:
docker logs n8n --tail 100 - Обновите систему для пересчёта лимитов:
python3 O6HOBA.py - При обновлении автоматически настраивается
N8N_HEAP_SIZE= 75% отN8N_MEM_LIMIT
- Проверьте логи:
- Ollama не справляется с эмбеддингами:
- Workflow использует
nomic-embed-textдля векторизации - Большие файлы создают много чанков → много запросов к Ollama
- Workflow оптимизирован:
chunkSize=1000(раньше было 300)
- Workflow использует
- PostgreSQL pgvector OOM:
- HNSW индекс требует RAM при массовой вставке
- Увеличьте лимит: в
.envизменитеPOSTGRES_MEM_LIMIT
Диагностика:
# Какой контейнер упал?
docker ps -a | grep -E "(Exited|OOM)"
# Проверить OOM killer
dmesg | grep -i "killed process"
# Мониторинг памяти в реальном времени
docker statsПроблемы с Code нодами
Problem: Unknown error или JsTaskRunnerSandbox в Code нодах
Solution:
# 1. Проверьте что контейнер runners запущен
docker ps | grep n8n-runners
# 2. Проверьте логи runners
docker logs n8n-runners
# 3. Если runners не запускается — обновите систему
python3 O6HOBA.py
# 4. Или перезапустите вручную
docker compose -p localai down
python3 start_services.py --profile <your-profile> --environment <your-env>Если миграция с Internal Mode:
При обновлении с версии без External Mode, скрипт O6HOBA.py автоматически:
- Генерирует
N8N_RUNNERS_AUTH_TOKEN - Добавляет его в
.env - Запускает новый контейнер
n8n-runners
Access Ports
External (via Caddy):
- N8N: http://localhost:8001 or https://{N8N_HOSTNAME}
- Supabase: http://localhost:8005 or https://{SUPABASE_HOSTNAME}
Internal (Docker network):
- N8N:
n8n:5678 - N8N Task Broker:
n8n:5679(для n8n-runners) - N8N Runners:
n8n-runners(без портов, подключается к broker) - Ollama:
ollama:11434 - Whisper:
whisper:8000 - Qdrant:
qdrant:6333 - PostgreSQL (N8N):
postgres:5432 - PostgreSQL (Supabase):
db:5432 - Kong (Supabase API):
kong:8000 - Squid Proxy:
squid:3128(только при PROXY_ENABLED=true)
Key Architectural Patterns
- Init Container Pattern: Used for N8N workflow import and Ollama model downloads
- Sparse Git Checkout: Supabase repo cloned with only
docker/directory to save bandwidth - Healthcheck Dependencies: PostgreSQL healthcheck prevents race conditions during startup
- Dual-Environment Support: Same compose files work for private (localhost) and public (domain) deployments
- Resource Limits: Auto-calculated from system specs, stored in
.env, applied via Docker deploy resources - Custom Image Builds: N8N image extended with FFmpeg, requires manual rebuild on upstream updates
- Task Runners External Mode: Code nodes execute in separate
n8n-runnerscontainer for isolation, security, and stability. Broker communicates on port 5679 viaN8N_RUNNERS_AUTH_TOKEN - Optional Proxy Profile: Squid proxy routes API requests through external proxy when
PROXY_ENABLED=true. Uses Docker Composeproxyprofile for conditional activation
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

