name: dify services: # =========================================================================== # Database # =========================================================================== dify-db: image: postgres:15-alpine restart: unless-stopped environment: POSTGRES_USER: ${DB_USERNAME} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_DATABASE} PGDATA: /var/lib/postgresql/data/pgdata command: > postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}' -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}' -c 'work_mem=${POSTGRES_WORK_MEM:-4MB}' -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}' -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}' volumes: - dify-db-data:/var/lib/postgresql/data healthcheck: test: [ "CMD", "pg_isready", "-h", "dify-db", "-U", "${DB_USERNAME:-postgres}", "-d", "${DB_DATABASE:-dify}", ] interval: 5s timeout: 3s retries: 30 networks: - dify # =========================================================================== # Cache / Queue # =========================================================================== dify-redis: image: redis:7-alpine restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - dify-redis-data:/data healthcheck: test: [ "CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG", ] interval: 5s timeout: 3s retries: 10 networks: - dify # =========================================================================== # SSRF Proxy (sandbox traffic goes through this to prevent SSRF attacks) # =========================================================================== dify-ssrf-proxy: image: ubuntu/squid:latest restart: unless-stopped volumes: - ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template - ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh entrypoint: [ "sh", "-c", "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh", ] environment: HTTP_PORT: ${SSRF_HTTP_PORT:-3128} COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid} REVERSE_PROXY_PORT: ${SSRF_REVERSE_PROXY_PORT:-8194} SANDBOX_HOST: dify-sandbox SANDBOX_PORT: ${SANDBOX_PORT:-8194} networks: - dify # =========================================================================== # Sandbox (secure Python code execution) # =========================================================================== dify-sandbox: image: langgenius/dify-sandbox:0.2.15 restart: unless-stopped environment: API_KEY: ${SANDBOX_API_KEY} GIN_MODE: ${SANDBOX_GIN_MODE:-release} WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15} ENABLE_NETWORK: ${SANDBOX_ENABLE_NETWORK:-true} HTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://dify-ssrf-proxy:3128} HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://dify-ssrf-proxy:3128} SANDBOX_PORT: ${SANDBOX_PORT:-8194} volumes: - ./dify-sandbox-dependencies:/dependencies - ./dify-sandbox-conf:/conf healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8194/health"] interval: 30s timeout: 5s retries: 3 depends_on: dify-ssrf-proxy: condition: service_started networks: - dify # =========================================================================== # Init permissions (upstream parity for bind-mounted storage) # =========================================================================== dify-init-permissions: image: busybox:latest restart: "no" command: - sh - -c - | FLAG_FILE="/app/api/storage/.init_permissions" if [ -f "$${FLAG_FILE}" ]; then echo "Permissions already initialized. Exiting." exit 0 fi echo "Initializing permissions for /app/api/storage" chown -R ${DIFY_STORAGE_UID:-1001}:${DIFY_STORAGE_GID:-1001} /app/api/storage && touch "$${FLAG_FILE}" echo "Permissions initialized. Exiting." volumes: - ./storage:/app/api/storage # =========================================================================== # API (backend) # =========================================================================== dify-api: image: langgenius/dify-api:1.14.2 restart: unless-stopped depends_on: dify-init-permissions: condition: service_completed_successfully dify-db: condition: service_healthy dify-redis: condition: service_healthy dify-plugin-daemon: condition: service_started dify-weaviate: condition: service_started environment: MODE: api # Core SECRET_KEY: ${SECRET_KEY} INIT_PASSWORD: ${INIT_PASSWORD} DEPLOY_ENV: ${DEPLOY_ENV:-PRODUCTION} MIGRATION_ENABLED: ${MIGRATION_ENABLED:-true} # Database DB_HOST: dify-db DB_PORT: 5432 DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} DB_DATABASE: ${DB_DATABASE} # Redis REDIS_HOST: dify-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD} REDIS_USE_SSL: ${REDIS_USE_SSL:-false} # Storage STORAGE_TYPE: ${STORAGE_TYPE:-opendal} STORAGE_LOCAL_PATH: ${STORAGE_LOCAL_PATH:-storage} OPENDAL_SCHEME: ${OPENDAL_SCHEME:-fs} OPENDAL_ROOT: ${OPENDAL_ROOT:-storage} # Vector Store VECTOR_STORE: ${VECTOR_STORE:-weaviate} WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://dify-weaviate:8080} WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih} # URLs CONSOLE_API_URL: ${CONSOLE_API_URL:-} CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-} SERVICE_API_URL: ${SERVICE_API_URL:-} APP_API_URL: ${APP_API_URL:-} APP_WEB_URL: ${APP_WEB_URL:-} FILES_URL: ${FILES_URL:-} INTERNAL_FILES_URL: ${INTERNAL_FILES_URL:-} # LLM Provider (Venice.ai — OpenAI-compatible) OPENAI_API_KEY: ${VENICE_API_KEY:-} OPENAI_API_BASE: ${VENICE_API_BASE:-https://api.venice.ai/api/v1} # Logging LOG_LEVEL: ${LOG_LEVEL:-INFO} DEBUG: ${DEBUG:-false} FLASK_DEBUG: ${FLASK_DEBUG:-false} # Plugins PLUGIN_DAEMON_KEY: ${PLUGIN_DAEMON_KEY} PLUGIN_DAEMON_URL: http://dify-plugin-daemon:5002 PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0} PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost} PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003} PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800} PLUGIN_DIFY_INNER_API_KEY: ${PLUGIN_DIFY_INNER_API_KEY} PLUGIN_DIFY_INNER_API_URL: http://dify-api:5001 INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY} FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-false} volumes: - ./storage:/app/api/storage networks: - dify # =========================================================================== # Worker (Celery background worker) # =========================================================================== dify-worker: image: langgenius/dify-api:1.14.2 restart: unless-stopped depends_on: dify-init-permissions: condition: service_completed_successfully dify-db: condition: service_healthy dify-redis: condition: service_healthy dify-weaviate: condition: service_started environment: MODE: worker # Core SECRET_KEY: ${SECRET_KEY} DEPLOY_ENV: ${DEPLOY_ENV:-PRODUCTION} # Database DB_HOST: dify-db DB_PORT: 5432 DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} DB_DATABASE: ${DB_DATABASE} # Redis REDIS_HOST: dify-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD} REDIS_USE_SSL: ${REDIS_USE_SSL:-false} # Storage STORAGE_TYPE: ${STORAGE_TYPE:-opendal} STORAGE_LOCAL_PATH: ${STORAGE_LOCAL_PATH:-storage} OPENDAL_SCHEME: ${OPENDAL_SCHEME:-fs} OPENDAL_ROOT: ${OPENDAL_ROOT:-storage} # Vector Store VECTOR_STORE: ${VECTOR_STORE:-weaviate} WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://dify-weaviate:8080} WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih} # LLM Provider (Venice.ai — OpenAI-compatible) OPENAI_API_KEY: ${VENICE_API_KEY:-} OPENAI_API_BASE: ${VENICE_API_BASE:-https://api.venice.ai/api/v1} # Logging LOG_LEVEL: ${LOG_LEVEL:-INFO} DEBUG: ${DEBUG:-false} # Plugins PLUGIN_DAEMON_KEY: ${PLUGIN_DAEMON_KEY} PLUGIN_DAEMON_URL: http://dify-plugin-daemon:5002 PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost} PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003} PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800} PLUGIN_DIFY_INNER_API_KEY: ${PLUGIN_DIFY_INNER_API_KEY} PLUGIN_DIFY_INNER_API_URL: http://dify-api:5001 INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY} FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-false} # Celery CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@dify-redis:6379/0 CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@dify-redis:6379/0 volumes: - ./storage:/app/api/storage healthcheck: test: [ "CMD-SHELL", "celery -A celery_healthcheck.celery inspect ping", ] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - dify # =========================================================================== # Worker Beat (Celery periodic task scheduler) # =========================================================================== dify-worker-beat: image: langgenius/dify-api:1.14.2 restart: unless-stopped depends_on: dify-init-permissions: condition: service_completed_successfully dify-db: condition: service_healthy dify-redis: condition: service_healthy environment: MODE: beat # Core SECRET_KEY: ${SECRET_KEY} DEPLOY_ENV: ${DEPLOY_ENV:-PRODUCTION} # Database DB_HOST: dify-db DB_PORT: 5432 DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} DB_DATABASE: ${DB_DATABASE} # Redis REDIS_HOST: dify-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD} REDIS_USE_SSL: ${REDIS_USE_SSL:-false} # Celery CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@dify-redis:6379/0 CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@dify-redis:6379/0 networks: - dify # =========================================================================== # Plugin Daemon # =========================================================================== dify-plugin-daemon: image: langgenius/dify-plugin-daemon:0.6.1-local restart: unless-stopped depends_on: dify-db: condition: service_healthy dify-redis: condition: service_healthy environment: # Database DB_HOST: dify-db DB_PORT: 5432 DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin} DB_SSL_MODE: ${DB_SSL_MODE:-disable} # Redis REDIS_HOST: dify-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD} # Plugin Daemon SERVER_PORT: ${PLUGIN_DAEMON_PORT:-5002} SERVER_KEY: ${PLUGIN_DAEMON_KEY} MAX_PLUGIN_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800} PPROF_ENABLED: ${PLUGIN_PPROF_ENABLED:-false} # Dify API connection DIFY_INNER_API_KEY: ${PLUGIN_DIFY_INNER_API_KEY} DIFY_INNER_API_URL: http://dify-api:5001 # Debugging PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0} PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003} # Storage PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local} PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage} PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd} PLUGIN_INSTALLED_PATH: ${PLUGIN_INSTALLED_PATH:-plugin} PLUGIN_PACKAGE_CACHE_PATH: ${PLUGIN_PACKAGE_CACHE_PATH:-plugin_packages} PLUGIN_MEDIA_CACHE_PATH: ${PLUGIN_MEDIA_CACHE_PATH:-assets} # Python PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120} PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600} # Misc FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true} # Plugin stdio PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024} PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880} PIP_MIRROR_URL: ${PIP_MIRROR_URL:-} volumes: - ./storage-plugin-daemon:/app/storage ports: - ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003} networks: - dify # =========================================================================== # Web (Next.js frontend) # =========================================================================== dify-web: image: langgenius/dify-web:1.14.2 restart: unless-stopped environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} SERVER_CONSOLE_API_URL: http://dify-api:5001 APP_API_URL: ${APP_API_URL:-} NEXT_PUBLIC_SOCKET_URL: ${NEXT_PUBLIC_SOCKET_URL:-} NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-1} TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000} CSP_WHITELIST: ${CSP_WHITELIST:-} ALLOW_EMBED: ${ALLOW_EMBED:-false} MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai} MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} depends_on: - dify-api networks: - dify # =========================================================================== # Nginx (reverse proxy) # =========================================================================== dify-nginx: image: nginx:alpine restart: unless-stopped depends_on: - dify-api - dify-web volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/proxy.conf:/etc/nginx/proxy.conf - ./nginx/conf.d:/etc/nginx/conf.d - ./storage:/app/storage:ro ports: - ${EXPOSE_NGINX_PORT:-80}:80 - ${EXPOSE_NGINX_SSL_PORT:-443}:443 networks: - dify - external_network # =========================================================================== # Vector Store (Weaviate) # =========================================================================== dify-weaviate: image: semitechnologies/weaviate:1.27.0 restart: unless-stopped volumes: - ./dify-weaviate-data:/var/lib/weaviate environment: PERSISTENCE_DATA_PATH: ${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate} QUERY_DEFAULTS_LIMIT: ${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25} ENABLE_MODULES: ${WEAVIATE_ENABLE_MODULES:-text2vec-voyageai} DEFAULT_VECTORIZER_MODULE: ${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-text2vec-voyageai} VOYAGEAI_APIKEY: ${VOYAGEAI_API_KEY:-} CLUSTER_HOSTNAME: ${WEAVIATE_CLUSTER_HOSTNAME:-node1} AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: ${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false} AUTHENTICATION_APIKEY_ENABLED: ${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true} AUTHENTICATION_APIKEY_ALLOWED_KEYS: ${WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih} AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai} AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true} AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai} DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false} ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false} ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false} ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false} networks: - dify networks: dify: name: dify # driver: bridge external_network: name: ${NETWORKS_EXTERNAL_NAME:-swag} external: true volumes: dify-db-data: driver: local dify-redis-data: driver: local