mirror of
https://github.com/Dokploy/templates.git
synced 2026-07-16 19:35:26 +02:00
Dify 1.15.0 (open-source LLM app development platform): api + worker + worker_beat + web + pgvector PostgreSQL (also used as the vector store) + redis + sandbox + ssrf_proxy (squid) + plugin_daemon, fronted by an internal nginx gateway that mirrors the upstream path routing. Closes #88 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
257 lines
7.4 KiB
YAML
257 lines
7.4 KiB
YAML
# Dify - open-source LLM app development platform
|
|
# Adapted from the official docker/docker-compose.yaml (tag 1.15.0).
|
|
# Minimal functional stack: api + worker + worker_beat + web + postgres
|
|
# (pgvector, reused as the vector store) + redis + sandbox + ssrf_proxy
|
|
# + plugin_daemon, fronted by a lightweight internal nginx gateway that
|
|
# mirrors the upstream path routing (TLS terminates at Traefik).
|
|
|
|
x-shared-api-env: &shared-api-env
|
|
LOG_LEVEL: INFO
|
|
DEPLOY_ENV: PRODUCTION
|
|
SECRET_KEY: ${SECRET_KEY}
|
|
MIGRATION_ENABLED: "true"
|
|
# Public URLs - a single domain, path-routed like the upstream nginx
|
|
CONSOLE_API_URL: https://${DIFY_DOMAIN}
|
|
CONSOLE_WEB_URL: https://${DIFY_DOMAIN}
|
|
SERVICE_API_URL: https://${DIFY_DOMAIN}
|
|
APP_API_URL: https://${DIFY_DOMAIN}
|
|
APP_WEB_URL: https://${DIFY_DOMAIN}
|
|
FILES_URL: https://${DIFY_DOMAIN}
|
|
INTERNAL_FILES_URL: http://api:5001
|
|
TRIGGER_URL: https://${DIFY_DOMAIN}
|
|
ENDPOINT_URL_TEMPLATE: https://${DIFY_DOMAIN}/e/{hook_id}
|
|
# The dedicated api_websocket collaboration service is not deployed
|
|
ENABLE_COLLABORATION_MODE: "false"
|
|
WEB_API_CORS_ALLOW_ORIGINS: "*"
|
|
CONSOLE_CORS_ALLOW_ORIGINS: "*"
|
|
# PostgreSQL
|
|
DB_USERNAME: postgres
|
|
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
|
DB_HOST: db
|
|
DB_PORT: "5432"
|
|
DB_DATABASE: dify
|
|
# Redis / Celery
|
|
REDIS_HOST: redis
|
|
REDIS_PORT: "6379"
|
|
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
|
REDIS_DB: "0"
|
|
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/1
|
|
# File storage on a local volume
|
|
STORAGE_TYPE: opendal
|
|
OPENDAL_SCHEME: fs
|
|
OPENDAL_FS_ROOT: storage
|
|
# Vector store: pgvector, reusing the same PostgreSQL instance
|
|
VECTOR_STORE: pgvector
|
|
PGVECTOR_HOST: db
|
|
PGVECTOR_PORT: "5432"
|
|
PGVECTOR_USER: postgres
|
|
PGVECTOR_PASSWORD: ${POSTGRES_PASSWORD}
|
|
PGVECTOR_DATABASE: dify
|
|
PGVECTOR_MIN_CONNECTION: "1"
|
|
PGVECTOR_MAX_CONNECTION: "5"
|
|
# Code execution sandbox
|
|
CODE_EXECUTION_ENDPOINT: http://sandbox:8194
|
|
CODE_EXECUTION_API_KEY: ${SANDBOX_API_KEY}
|
|
# SSRF proxy (squid) for user-triggered outbound requests
|
|
SSRF_PROXY_HTTP_URL: http://ssrf_proxy:3128
|
|
SSRF_PROXY_HTTPS_URL: http://ssrf_proxy:3128
|
|
# Plugin daemon (model providers / tools are plugins since Dify 1.0)
|
|
PLUGIN_DAEMON_URL: http://plugin_daemon:5002
|
|
PLUGIN_DAEMON_KEY: ${PLUGIN_DAEMON_KEY}
|
|
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_INNER_API_KEY}
|
|
PLUGIN_MAX_PACKAGE_SIZE: "52428800"
|
|
PLUGIN_REMOTE_INSTALL_HOST: localhost
|
|
PLUGIN_REMOTE_INSTALL_PORT: "5003"
|
|
MARKETPLACE_ENABLED: "true"
|
|
MARKETPLACE_API_URL: https://marketplace.dify.ai
|
|
|
|
services:
|
|
nginx:
|
|
image: nginx:1.27-alpine
|
|
restart: always
|
|
volumes:
|
|
- ../files/dify-nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
|
depends_on:
|
|
api:
|
|
condition: service_healthy
|
|
web:
|
|
condition: service_started
|
|
plugin_daemon:
|
|
condition: service_started
|
|
|
|
# The dify-api image runs as the non-root user 1001, so the shared
|
|
# storage volume has to be handed over to it once (same trick as the
|
|
# upstream init_permissions container).
|
|
init_permissions:
|
|
image: busybox:1.36
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
FLAG_FILE="/app/api/storage/.init_permissions"
|
|
if [ -f "$$FLAG_FILE" ]; then
|
|
echo "Permissions already initialized."
|
|
exit 0
|
|
fi
|
|
echo "Initializing permissions for /app/api/storage"
|
|
chown -R 1001:1001 /app/api/storage && touch "$$FLAG_FILE"
|
|
volumes:
|
|
- dify-app-storage:/app/api/storage
|
|
restart: "no"
|
|
|
|
api:
|
|
image: langgenius/dify-api:1.15.0
|
|
restart: always
|
|
environment:
|
|
<<: *shared-api-env
|
|
MODE: api
|
|
depends_on:
|
|
init_permissions:
|
|
condition: service_completed_successfully
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
volumes:
|
|
- dify-app-storage:/app/api/storage
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5001/health"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 20
|
|
start_period: 120s
|
|
|
|
worker:
|
|
image: langgenius/dify-api:1.15.0
|
|
restart: always
|
|
environment:
|
|
<<: *shared-api-env
|
|
MODE: worker
|
|
depends_on:
|
|
init_permissions:
|
|
condition: service_completed_successfully
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
volumes:
|
|
- dify-app-storage:/app/api/storage
|
|
|
|
worker_beat:
|
|
image: langgenius/dify-api:1.15.0
|
|
restart: always
|
|
environment:
|
|
<<: *shared-api-env
|
|
MODE: beat
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
web:
|
|
image: langgenius/dify-web:1.15.0
|
|
restart: always
|
|
environment:
|
|
CONSOLE_API_URL: https://${DIFY_DOMAIN}
|
|
APP_API_URL: https://${DIFY_DOMAIN}
|
|
SERVER_CONSOLE_API_URL: http://api:5001
|
|
ENABLE_COLLABORATION_MODE: "false"
|
|
MARKETPLACE_API_URL: https://marketplace.dify.ai
|
|
MARKETPLACE_URL: https://marketplace.dify.ai
|
|
NEXT_TELEMETRY_DISABLED: "1"
|
|
|
|
db:
|
|
image: pgvector/pgvector:pg16
|
|
restart: always
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: dify
|
|
PGDATA: /var/lib/postgresql/data/pgdata
|
|
volumes:
|
|
- dify-db-data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres -d dify"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 30
|
|
|
|
redis:
|
|
image: redis:6-alpine
|
|
restart: always
|
|
environment:
|
|
REDISCLI_AUTH: ${REDIS_PASSWORD}
|
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
|
volumes:
|
|
- dify-redis-data:/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "redis-cli ping | grep -q PONG"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 30
|
|
|
|
sandbox:
|
|
image: langgenius/dify-sandbox:0.2.15
|
|
restart: always
|
|
environment:
|
|
API_KEY: ${SANDBOX_API_KEY}
|
|
GIN_MODE: release
|
|
WORKER_TIMEOUT: "15"
|
|
ENABLE_NETWORK: "true"
|
|
HTTP_PROXY: http://ssrf_proxy:3128
|
|
HTTPS_PROXY: http://ssrf_proxy:3128
|
|
SANDBOX_PORT: "8194"
|
|
volumes:
|
|
- dify-sandbox-deps:/dependencies
|
|
|
|
ssrf_proxy:
|
|
image: ubuntu/squid:latest
|
|
restart: always
|
|
volumes:
|
|
- ../files/dify-squid.conf:/etc/squid/squid.conf:ro
|
|
|
|
plugin_daemon:
|
|
image: langgenius/dify-plugin-daemon:0.6.3-local
|
|
restart: always
|
|
environment:
|
|
DB_HOST: db
|
|
DB_PORT: "5432"
|
|
DB_USERNAME: postgres
|
|
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
|
DB_DATABASE: dify_plugin
|
|
DB_SSL_MODE: disable
|
|
REDIS_HOST: redis
|
|
REDIS_PORT: "6379"
|
|
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
|
SERVER_PORT: "5002"
|
|
SERVER_KEY: ${PLUGIN_DAEMON_KEY}
|
|
MAX_PLUGIN_PACKAGE_SIZE: "52428800"
|
|
DIFY_INNER_API_URL: http://api:5001
|
|
DIFY_INNER_API_KEY: ${PLUGIN_INNER_API_KEY}
|
|
PLUGIN_REMOTE_INSTALLING_HOST: 0.0.0.0
|
|
PLUGIN_REMOTE_INSTALLING_PORT: "5003"
|
|
PLUGIN_WORKING_PATH: /app/storage/cwd
|
|
FORCE_VERIFYING_SIGNATURE: "true"
|
|
PYTHON_ENV_INIT_TIMEOUT: "120"
|
|
PLUGIN_MAX_EXECUTION_TIMEOUT: "600"
|
|
PLUGIN_STORAGE_TYPE: local
|
|
PLUGIN_STORAGE_LOCAL_ROOT: /app/storage
|
|
PLUGIN_INSTALLED_PATH: plugin
|
|
PLUGIN_PACKAGE_CACHE_PATH: plugin_packages
|
|
PLUGIN_MEDIA_CACHE_PATH: assets
|
|
volumes:
|
|
- dify-plugin-storage:/app/storage
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
volumes:
|
|
dify-app-storage:
|
|
dify-db-data:
|
|
dify-redis-data:
|
|
dify-sandbox-deps:
|
|
dify-plugin-storage:
|