How Dify Offline Plugin Packages Work with `--no-index` and `--find-links`

The dify-plugin-repackaging utility creates self-contained wheel files that install in air-gapped environments using pip install --no-index --find-links to bypass PyPI and resolve dependencies exclusively from a local directory.

The junjiem/dify-plugin-repackaging repository provides a specialized build utility for creating self-contained, offline-installable plugin packages for the Dify platform. By wrapping compiled Go binaries in Python wheel metadata, the tool generates platform-specific .whl files that distribute without internet connectivity. This workflow leverages specific pip flags to guarantee reproducible installations in secure or isolated environments.

The Three-Stage Offline Packaging Workflow

Stage 1: Building the Plugin Wheels

The plugin_repackaging.sh script serves as the primary build orchestrator. Located in the repository root, it compiles the plugin binary for each target platform using go build, then packages the result into a Python wheel with the required metadata. All generated wheels are placed into a local package store directory (./packages by default), creating a complete offline repository.

Stage 2: Publishing the Store

Once built, the ./packages directory functions as a standalone distribution unit. You can transfer this folder to target machines via USB drive, internal HTTP server, or CI artifact storage. Because the directory contains all necessary wheel files, no external PyPI repository connection is required for distribution to air-gapped environments.

On the target host, pip installs the plugin using two specific flags that work in tandem. The --no-index flag prevents pip from querying the public PyPI index entirely, while --find-links points pip to the local ./packages directory containing the wheel files. This combination forces pip to resolve the plugin and its dependencies exclusively from the filesystem, eliminating all network calls.

--no-index guarantees that pip never attempts to reach out to the public PyPI index or any external package repository. This behavior is essential for environments with strict security controls or no internet access, ensuring that the installation process fails safely rather than hanging attempting external connections.

--find-links supplies pip with a custom "index" in the form of a simple directory or HTML file containing wheel files. Pip treats each .whl file in the specified directory as a package candidate and resolves the requested version directly from the filesystem without requiring a full PyPI-compatible server infrastructure.

The plugin_repackaging.sh script also generates a requirements.txt file that pins the exact plugin version. This allows the installation command to reference specific builds while maintaining the offline constraint.

Practical Implementation Steps

Build wheels for multiple target platforms on your build machine:

./plugin_repackaging.sh build \
    --output-dir ./packages \
    --targets linux/amd64 darwin/arm64

Transfer the generated package store to the offline target host:

scp -r ./packages user@offline-host:/opt/dify-plugin

Install the plugin offline using the generated requirements file:

pip install --no-index --find-links ./packages -r requirements.txt

For single-wheel installations without a requirements file, reference the wheel directly:

pip install --no-index --find-links ./packages dify_plugin-1.2.3-py3-none-any.whl

Key Files and Their Roles

  • plugin_repackaging.sh: The main build script that compiles Go assets, creates platform-specific wheels, and writes the requirements.txt file.
  • ./packages/: The default local package store directory containing the generated .whl files (e.g., dify-plugin-linux-amd64.whl).
  • requirements.txt: Auto-generated file containing exact version pins to ensure reproducible installations across environments.
  • Dockerfile: Provides a containerized build environment for running the packaging script reproducibly.
  • images/install_plugin_via_local.png: Visual diagram illustrating the offline installation workflow.

Summary

  • The dify-plugin-repackaging tool generates platform-specific wheels containing pre-compiled binaries for the Dify platform.
  • The ./packages directory acts as a self-contained package store that requires no external PyPI access for distribution.
  • --no-index prevents pip from accessing external package indexes, ensuring compatibility with air-gapped networks.
  • --find-links directs pip to resolve and install packages exclusively from the local wheel directory.
  • This workflow guarantees that the exact binary version built on the build machine installs on the target host without requiring compilation tools or internet access.

Frequently Asked Questions

What is the purpose of the --no-index flag in pip?

The --no-index flag tells pip to ignore the default PyPI package index and any other configured indexes. This prevents pip from attempting to download packages from the internet, making it essential for installing packages in offline or air-gapped environments where external network access is restricted or unavailable.

While --index-url points pip to an alternative PyPI-compatible repository server (such as a private Nexus or Artifactory instance), --find-links points to a simple directory path or HTML file containing wheel files. In the context of dify-plugin-repackaging, --find-links treats the local ./packages folder as a flat repository, allowing pip to discover and install wheels without hosting a full package index server.

Can I install a single wheel file without using requirements.txt?

Yes. If you only need to install a specific plugin version, you can reference the wheel file directly in the pip command: pip install --no-index --find-links ./packages dify_plugin-1.2.3-py3-none-any.whl. This approach bypasses the need for a requirements.txt file while still utilizing the offline package store and preventing PyPI access.

Why does the build process create Python wheels instead of distributing raw binaries?

Wheels are the standard Python packaging format that pip understands natively. By wrapping the compiled Go binary in a wheel structure according to Python packaging standards, the plugin_repackaging.sh script allows pip to handle installation, dependency resolution, and uninstallation consistently across different platforms. This approach ensures the compiled binary installs to the correct location within the Python environment while maintaining compatibility with standard Python tooling.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →