# Dify.ai Workflow Platform

## Overview

[Dify.ai](https://github.com/langgenius/dify) is an open-source LLM application development platform with **114K+ GitHub stars**. It combines a visual workflow builder, retrieval-augmented generation (RAG) pipeline, agent orchestration, model management, and a one-click API deployment layer into a single self-hostable stack.

On **Clore.ai** you can run the full Dify stack — including its Postgres database, Redis cache, Weaviate vector store, Nginx reverse proxy, API workers, and web frontend — on a rented GPU server for as little as **$0.20–$0.35/hr** (RTX 3090/4090). The GPU is optional for Dify itself, but becomes essential when you integrate local model inference through Ollama or vLLM backends.

**Key capabilities:**

* 🔄 **Visual workflow builder** — drag-and-drop LLM pipelines with branching, loops, and conditional logic
* 📚 **RAG pipeline** — upload PDFs, URLs, Notion pages; chunking + embedding + retrieval all managed in UI
* 🤖 **Agent mode** — ReAct and function-calling agents with tool use (web search, code interpreter, custom APIs)
* 🚀 **API-first** — every app generates a REST endpoint and SDK snippets instantly
* 🔌 **100+ model integrations** — OpenAI, Anthropic, Mistral, Cohere, plus local models via Ollama/vLLM
* 🏢 **Multi-tenant** — teams, workspaces, RBAC, usage quotas

***

## Requirements

Dify runs as a multi-container Docker Compose stack. The minimum viable server for development is a CPU-only instance; for production with local model inference you'll want a GPU node.

| Configuration               | GPU             | VRAM  | System RAM | Disk   | Clore.ai Price   |
| --------------------------- | --------------- | ----- | ---------- | ------ | ---------------- |
| **Minimal** (API keys only) | None / CPU      | —     | 8 GB       | 30 GB  | \~$0.05/hr (CPU) |
| **Standard**                | RTX 3080        | 10 GB | 16 GB      | 50 GB  | \~$0.15/hr       |
| **Recommended**             | RTX 3090 / 4090 | 24 GB | 32 GB      | 80 GB  | $0.20–0.35/hr    |
| **Production + Local LLM**  | A100 80 GB      | 80 GB | 64 GB      | 200 GB | \~$1.10/hr       |
| **High-throughput**         | H100 SXM        | 80 GB | 128 GB     | 500 GB | \~$2.50/hr       |

> **Tip:** If you only use cloud API providers (OpenAI, Anthropic, etc.), any 2-core CPU instance with 8 GB RAM works. A GPU matters only when running local models via Ollama or vLLM — see [GPU Acceleration](#gpu-acceleration) below.

### Disk note

Weaviate and Postgres data grow quickly with document uploads. Provision **at least 50 GB** and mount persistent storage via Clore.ai's volume options.

***

## Quick Start

### 1. Rent a Clore.ai server

Browse to [clore.ai](https://clore.ai), filter by your desired GPU, and deploy a server with:

* **Docker** pre-installed (all Clore images include it)
* Exposed ports **80** and **443** (add custom ports in the offer settings if needed)
* SSH access enabled

### 2. Connect and prepare the server

```bash
# SSH into your Clore server
ssh root@<clore-server-ip> -p <ssh-port>

# Update system packages
apt-get update && apt-get upgrade -y

# Verify Docker is available
docker --version
docker compose version   # Should be v2.x
```

### 3. Clone Dify and launch

```bash
# Clone the repository
git clone https://github.com/langgenius/dify.git
cd dify/docker

# Copy the example environment file
cp .env.example .env

# (Optional) Edit settings before launch
nano .env

# Pull all images and start all services in background
docker compose up -d

# Watch logs during startup (takes 2-3 minutes first run)
docker compose logs -f
```

### 4. Verify all services are healthy

```bash
# Check container status
docker compose ps

# Expected output:
# NAME                    STATUS
# docker-api-1            Up (healthy)
# docker-web-1            Up (healthy)
# docker-worker-1         Up (healthy)
# docker-nginx-1          Up
# docker-db-1             Up (healthy)
# docker-redis-1          Up (healthy)
# docker-weaviate-1       Up (healthy)
# docker-sandbox-1        Up (healthy)
```

### 5. Access the web UI

Open your browser and navigate to:

```
http://<clore-server-ip>:80
```

On first launch, Dify will redirect you to the setup wizard to create the admin account. Complete the wizard, then log in.

***

## Configuration

All configuration lives in `dify/docker/.env`. Here are the most important settings:

### Essential environment variables

```bash
# ── Secret Keys (CHANGE THESE) ──────────────────────────────────────────────
SECRET_KEY=your-super-secret-key-change-this-immediately
# Generate a strong key:
# python3 -c "import secrets; print(secrets.token_hex(32))"

# ── Application URL ──────────────────────────────────────────────────────────
# Set to your server's public IP or domain
CONSOLE_WEB_URL=http://<clore-server-ip>
APP_WEB_URL=http://<clore-server-ip>

# ── Database (Postgres) ─────────────────────────────────────────────────────
DB_USERNAME=postgres
DB_PASSWORD=difyai123456          # Change in production!
DB_HOST=db
DB_PORT=5432
DB_DATABASE=dify

# ── Redis ───────────────────────────────────────────────────────────────────
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=difyai123456       # Change in production!

# ── Storage (local disk by default) ─────────────────────────────────────────
STORAGE_TYPE=local
# Or use S3-compatible storage:
# STORAGE_TYPE=s3
# S3_ENDPOINT=https://s3.amazonaws.com
# S3_BUCKET_NAME=your-dify-bucket
# S3_ACCESS_KEY=...
# S3_SECRET_KEY=...

# ── Default LLM provider ─────────────────────────────────────────────────────
# Set in the UI after login, or pre-configure here:
# OPENAI_API_KEY=sk-...
```

### Changing the exposed port

By default Nginx listens on port **80**. To change it:

```bash
# In docker-compose.yaml, edit the nginx service:
# ports:
#   - "8080:80"   ← change 8080 to your preferred host port

# Then restart:
docker compose down && docker compose up -d
```

### Persistent data volumes

Dify's Compose file mounts these volumes by default:

```yaml
volumes:
  oradata:          # Postgres data
  redis_data:       # Redis AOF
  weaviate_data:    # Vector store
  app_storage:      # Uploaded documents and generated files
```

To back up:

```bash
# Stop services first, then tar the Docker volumes
docker compose stop
docker run --rm \
  -v docker_oradata:/data \
  -v $(pwd)/backups:/backup \
  alpine tar czf /backup/postgres-$(date +%Y%m%d).tar.gz /data
docker compose start
```

***

## GPU Acceleration

Dify's core platform is CPU-based, but you unlock local model inference by integrating **Ollama** or **vLLM** as model providers — both benefit enormously from a GPU.

### Option A: Ollama sidecar (easiest)

Run Ollama alongside Dify on the same Clore server:

```bash
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh

# Pull a model (e.g. Llama 3 8B)
ollama pull llama3:8b

# Verify GPU is used
ollama run llama3:8b "Hello!"
nvidia-smi   # Should show ollama process using VRAM
```

Then in Dify UI → **Settings → Model Providers → Ollama**:

* Base URL: `http://localhost:11434`
* Select your model and save

> For a full Ollama guide, see [language-models/ollama.md](https://docs.clore.ai/guides/language-models/ollama).

### Option B: vLLM sidecar (high-throughput)

```bash
# Run vLLM as a separate container with GPU passthrough
docker run -d \
  --name vllm \
  --gpus all \
  --runtime nvidia \
  -p 8000:8000 \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  -e HUGGING_FACE_HUB_TOKEN=<your-hf-token> \
  vllm/vllm-openai:latest \
  --model mistralai/Mistral-7B-Instruct-v0.2 \
  --dtype auto \
  --max-model-len 4096

# Verify endpoint
curl http://localhost:8000/v1/models
```

Then in Dify UI → **Settings → Model Providers → OpenAI-compatible**:

* Base URL: `http://localhost:8000/v1`
* API Key: `dummy`
* Model name: `mistralai/Mistral-7B-Instruct-v0.2`

> For full vLLM setup, see [language-models/vllm.md](https://docs.clore.ai/guides/language-models/vllm).

### GPU memory recommendations for local models

| Model              | VRAM Required | Recommended Clore GPU |
| ------------------ | ------------- | --------------------- |
| Llama 3 8B (Q4)    | 6 GB          | RTX 3060              |
| Llama 3 8B (FP16)  | 16 GB         | RTX 3090 / 4090       |
| Mistral 7B (Q4)    | 5 GB          | RTX 3060              |
| Llama 3 70B (Q4)   | 40 GB         | A100 40GB             |
| Llama 3 70B (FP16) | 140 GB        | 2× H100               |

***

## Tips & Best Practices

### Cost optimization on Clore.ai

```bash
# Use spot pricing — Dify's databases maintain state in volumes
# so you can stop/restart the instance cheaply

# Before stopping your Clore instance, dump the DB:
docker exec docker-db-1 pg_dump -U postgres dify > dify_backup_$(date +%Y%m%d).sql

# Compress the storage volume for transfer
tar czf dify_storage_$(date +%Y%m%d).tar.gz \
  $(docker volume inspect docker_app_storage --format '{{.Mountpoint}}')
```

### Enable HTTPS with Caddy (recommended for production)

```bash
# Add Caddy to docker-compose.yaml or run standalone
docker run -d \
  --name caddy \
  --network docker_default \
  -p 443:443 -p 80:80 \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  -v caddy_data:/data \
  caddy:latest

# Caddyfile contents:
# your-domain.com {
#     reverse_proxy nginx:80
# }
```

### Scale workers for heavy workloads

```bash
# Run 4 celery workers instead of 1
docker compose up -d --scale worker=4
```

### Monitor resource usage

```bash
# Live container stats
docker stats

# GPU utilization (if using local models)
watch -n1 nvidia-smi

# Dify application logs
docker compose logs -f api worker
```

### RAG performance tuning

* Set **chunk size** to 512–1024 tokens for most document types
* Enable **parent-child retrieval** for long documents in Dataset settings
* Use **hybrid search** (keyword + vector) for better recall on technical content
* Index documents during off-peak hours to avoid API rate limits

***

## Troubleshooting

### Services keep restarting

```bash
# Check logs for the failing service
docker compose logs --tail=50 api
docker compose logs --tail=50 worker

# Common cause: wrong SECRET_KEY or DB connection
# Ensure .env SECRET_KEY is set and unique
grep SECRET_KEY .env
```

### "Migration failed" on startup

```bash
# Run DB migrations manually
docker compose exec api flask db upgrade

# If that fails, check Postgres is healthy first
docker compose exec db pg_isready -U postgres
```

### Can't connect to Ollama from Dify

```bash
# Ollama by default binds to 127.0.0.1
# Change it to listen on all interfaces:
OLLAMA_HOST=0.0.0.0 ollama serve

# Or edit the systemd service:
systemctl edit ollama
# Add under [Service]:
# Environment="OLLAMA_HOST=0.0.0.0"
systemctl restart ollama

# Test from within a Dify container:
docker compose exec api curl http://host.docker.internal:11434/api/tags
```

### Out of disk space

```bash
# Check volume sizes
df -h
docker system df

# Remove unused images
docker image prune -a

# Weaviate logs can grow large — rotate them
docker compose exec weaviate truncate -s 0 /tmp/weaviate.log
```

### Weaviate vector store errors

```bash
# Reset Weaviate (WARNING: deletes all embeddings, re-index needed)
docker compose stop weaviate
docker volume rm docker_weaviate_data
docker compose up -d weaviate

# Then re-index your datasets in Dify UI → Datasets → [dataset] → Re-index
```

### Port 80 already in use

```bash
# Find what's using port 80
ss -tlnp | grep :80
# or
lsof -i :80

# Stop conflicting service or change Dify's nginx port in docker-compose.yaml
```

***

## Further Reading

* [Dify Official Documentation](https://docs.dify.ai)
* [Dify GitHub Repository](https://github.com/langgenius/dify)
* [Dify Self-hosting Guide](https://docs.dify.ai/getting-started/install-self-hosted/docker-compose)
* [Running Ollama on Clore.ai](https://docs.clore.ai/guides/language-models/ollama)
* [Running vLLM on Clore.ai](https://docs.clore.ai/guides/language-models/vllm)
* [Clore.ai GPU Comparison](https://docs.clore.ai/guides/getting-started/gpu-comparison)
* [Dify Community Discord](https://discord.gg/FngNHpbcY7)
