A Docker-based tool that rebuilds Dify plugin packages (.difypkg) so they can be installed on air-gapped / internet-disconnected Dify instances.
It bundles all Python dependencies as pre-built wheels into the package.
- ✨ Why This Tool?
- ✅ Prerequisites
- 📝 Quick Start
- ⚙️ Configuration
- ⚙️ How It Works
- ⚙️ Dify Platform Settings
- 🖥️ Running Locally (without Docker)
- 🙏 Acknowledgements
This tool runs directly inside the official langgenius/dify-plugin-daemon container image — the same image that Dify Community Edition uses to install and manage plugins. This means:
- Accurate dependency resolution — Python packages are resolved using the exact same Python version, system libraries, and
uvtoolchain that Dify uses at runtime. No version mismatches or missing native libraries. - Zero build step — No custom
Dockerfile, no image builds. Justdocker compose run.
Important
Wheels are downloaded for the CPU architecture of the machine running this tool. Make sure you run it on the same architecture (amd64 / arm64) as your production Dify environment.
- Docker host with the same CPU architecture as your containerized Dify Plugin Daemon (amd64 or arm64)
- Docker & Docker Compose
- Internet access (to download plugins and Python packages)
Note
If you are running the Dify Plugin Daemon locally instead of as a container, you can run the packager script directly without Docker. See 🖥️ Running Locally (without Docker) for details.
git clone https://github.com/kurokobo/dify-plugin-offline-packager.git
cd dify-plugin-offline-packager
# (Optional) Customize settings
cp .env.example .env# author/name:version
docker compose run --rm packager --marketplace "langgenius/openai:0.3.2"# owner/repo:tag:asset.difypkg
docker compose run --rm packager --github "junjiem/dify-plugin-agent-mcp_sse:0.2.4:agent-mcp_sse.difypkg"Place the .difypkg file in ./difypkg/, then run:
docker compose run --rm packager --local "difypkg/my-plugin.difypkg"Both the original and the offline-packaged file are saved to ./difypkg/:
difypkg/
langgenius-openai_0.3.2.difypkg ← original (online)
langgenius-openai_0.3.2-offline.difypkg ← offline-ready
All settings can be customised via the .env file (or environment variables):
| Variable | Default | Description |
|---|---|---|
DIFY_PLUGIN_DAEMON_VERSION |
0.5.3 |
Docker image tag for the official daemon image. Also used to download the dify-plugin CLI binary. |
MARKETPLACE_API_URL |
https://marketplace.dify.ai |
Dify Marketplace API URL |
GITHUB_API_URL |
https://github.com |
GitHub URL (set for GitHub Enterprise) |
PIP_INDEX_URL |
https://pypi.org/simple |
PyPI mirror URL (e.g. https://mirrors.aliyun.com/pypi/simple for Chinese users) |
docker compose runstarts the officialdify-plugin-daemoncontainer.- The entrypoint is overridden to
uv run scripts/packager.py. ./scripts/is bind-mounted read-only;./bin/and./difypkg/are mounted read-write.
- The entrypoint is overridden to
- Inside the container the script:
- Downloads the plugin (or reads a local file).
- Saves the original
.difypkgto./difypkg/. - Detects whether the plugin uses
pyproject.tomlorrequirements.txt:- pyproject.toml — injects
environments(current OS + Python) and removes[dependency-groups]frompyproject.toml, runsuv lockto pin exact versions, exports the pinned list viauv export, downloads wheels viauv run python -m pip download, patches the[tool.uv]section withno-index = trueandfind-links = ["./wheels/"], then deletesuv.lock(required because--no-indexand--frozenare conflicting options in uv). - requirements.txt — downloads wheels via
uv run python -m pip download, then prepends--no-index --find-links=./wheels/.
- pyproject.toml — injects
- Downloads the
dify-pluginCLI binary from GitHub (cached across runs). - Repacks the plugin with
dify-plugin plugin package.
To install offline-packaged plugins, you may need to adjust these Dify .env settings:
FORCE_VERIFYING_SIGNATURE=false— Allow installing unsigned plugins.ENFORCE_LANGGENIUS_PLUGIN_SIGNATURES=false— Allow installing unsigned official plugins.PLUGIN_MAX_PACKAGE_SIZE=524288000— Allow plugins up to 500 MB.NGINX_CLIENT_MAX_BODY_SIZE=500M— Raise the Nginx upload limit.
If you are running the Dify Plugin Daemon locally (not as a container), you can invoke the packager script directly on your machine instead of using Docker.
See docs/local-usage.md for the full instructions.
This project was inspired by junjiem/dify-plugin-repackaging. Thanks to @junjiem for the original idea and implementation.