Plugin Storage Configuration#
The Dify plugin daemon (langgenius/dify-plugin-daemon) uses a set of environment variables to control where plugin files, caches, and working data are stored. All storage variables are set in the plugin_daemon service block of docker-compose.yaml and can be overridden via docker/.env or docker/envs/core-services/plugin-daemon.env.example .
Docker Volume#
The daemon's entire storage tree lives under a single bind-mount :
./volumes/plugin_daemon → /app/storage (inside container)
./volumes/plugin_daemon is the host path relative to the docker/ directory. All path-based env vars below are resolved inside the container, so they all sit within this mount unless you change PLUGIN_STORAGE_LOCAL_ROOT.
Environment Variables#
The PLUGIN_STORAGE_TYPE variable selects the backend. All path variables below use PLUGIN_STORAGE_LOCAL_ROOT as their base when PLUGIN_STORAGE_TYPE=local :
| Variable | Default | Purpose |
|---|---|---|
PLUGIN_STORAGE_TYPE | local | Storage backend. local uses the filesystem; cloud options (S3, Azure, Aliyun OSS, Tencent COS, Volcengine TOS) are also supported. |
PLUGIN_STORAGE_LOCAL_ROOT | /app/storage | Absolute in-container root for all local storage. Maps to the Docker volume mount. |
PLUGIN_INSTALLED_PATH | plugin | Relative subdir (under PLUGIN_STORAGE_LOCAL_ROOT) where installed plugin directories are written. Full default path: /app/storage/plugin. |
PLUGIN_PACKAGE_CACHE_PATH | plugin_packages | Relative subdir for downloaded/cached plugin .difypkg package files. Full default: /app/storage/plugin_packages. |
PLUGIN_MEDIA_CACHE_PATH | assets | Relative subdir for cached plugin media/icons. Full default: /app/storage/assets. |
PLUGIN_WORKING_PATH | /app/storage/cwd | Absolute scratch directory the daemon uses while executing plugins. |
PLUGIN_STORAGE_OSS_BUCKET | (empty) | Required when PLUGIN_STORAGE_TYPE is an OSS-family backend. |
Cloud-backend credentials (S3 keys, Azure connection strings, Tencent/Aliyun/Volcengine secrets) are configured via the matching PLUGIN_S3_*, PLUGIN_AZURE_*, PLUGIN_TENCENT_COS_*, PLUGIN_ALIYUN_OSS_*, and PLUGIN_VOLCENGINE_TOS_* prefixed variables in the same block .
Configuration File Precedence#
The plugin daemon resolves env vars in this order (later sources win, following standard Docker Compose layering):
docker/envs/core-services/plugin-daemon.env(optional; copy fromplugin-daemon.env.example)docker/.env(always loaded, takes precedence)- Hardcoded
environment:block defaults indocker-compose.yaml(fallback when a variable is absent from all env files)
For most deployments, setting PLUGIN_STORAGE_TYPE and the relevant root/path variables in docker/.env is sufficient.
Operational Notes#
- Persisting plugins across restarts: Only
./volumes/plugin_daemonneeds to be backed up. It contains installed plugins, cached packages, and working state. - Stale directories after upgrades: The daemon scans
PLUGIN_INSTALLED_PATHon startup and matches directories to database records. After a version upgrade, old plugin version directories may no longer match records, loggingrecord not foundmessages. Runflask backfill-plugin-auto-upgradefrom theapicontainer and remove stale subdirectories to resolve this. - Separate plugin database: The daemon uses a dedicated
dify_plugindatabase (configurable viaDB_PLUGIN_DATABASE) — separate from the maindifyPostgreSQL database.