feat(pluginDaemon): expose shareProcessNamespace on pod spec#402
Merged
BorisPolonsky merged 1 commit intoBorisPolonsky:masterfrom Apr 20, 2026
Conversation
The embedded dify_plugin Python SDK (in every plugin's .venv) has an orphan-detection thread that calls os._exit(-1) when os.getppid()==1. This assumes Docker --init (tini) is injecting PID 1, which Docker Compose does by default. On Kubernetes the plugin-daemon container runs /app/main as PID 1, so every Python plugin subprocess self-exits ~500ms after launch and dispatch fails with "no proper instance". Setting shareProcessNamespace: true on the pod makes the K8s pause container PID 1, the daemon moves to PID >=2, and plugin subprocesses have PPID >1 so the SDK check passes. Defaults to false to preserve existing behaviour; users on K8s should set pluginDaemon.shareProcessNamespace=true.
BorisPolonsky
added a commit
that referenced
this pull request
Apr 20, 2026
Add a values.yaml note linking the pluginDaemon.shareProcessNamespace flag to the related pull request for operators who need the workaround.
BorisPolonsky
added a commit
that referenced
this pull request
Apr 20, 2026
) * fix(schema): add `pluginDaemon.shareProcessNamespace` to `values.schema.json` * feat(helm): configurable shareProcessNamespace across deployments * docs(dify): comment on shareProcessNamespace workaround for PR #402 Add a values.yaml note linking the pluginDaemon.shareProcessNamespace flag to the related pull request for operators who need the workaround.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add
pluginDaemon.shareProcessNamespacevalues key (defaultfalse) and interpolate it into the plugin-daemon Deployment's pod spec. This lets operators work around a design flaw in the embeddeddify_pluginPython SDK that makes plugins self-terminate on Kubernetes.Why
Every installed plugin ships its own copy of
dify_pluginin its.venv. The SDK'score/server/io_server.py::_parent_alive_checkruns as a background thread and callsos._exit(-1)wheneveros.getppid() == 1:This is a naive orphan-detection that assumes the container has an init process as PID 1 — which is true for Docker Compose (injects tini via
docker run --init/init: true) but not for Kubernetes by default. On K8s, the plugin-daemon container runs/app/mainas PID 1, so every Python plugin subprocess it spawns hasgetppid() == 1and self-exits ~500 ms after launch. The Go daemon'sscheduleLooprespawns, and the cycle repeats.Observable symptom:
ValidateProviderCredentialsand other SSE-dispatch calls fail withPluginDaemonInternalServerError: no proper instance. Inside the pod,ps -eo pid,ppid,etimeshows Python subprocesses cycling every ~3–4 s with PPID=1. This is reproducible on plain GKE withdify/dify 0.36.0+dify-plugin-daemon:0.5.8-local.Fix
Set
shareProcessNamespace: trueon the pod. Kubernetes then puts the pause container at PID 1 and the daemon at PID ≥ 2, so plugin subprocesses inherit PPID ≥ 2 and the SDK's check stops firing.This PR:
pluginDaemon.shareProcessNamespacetocharts/dify/values.yaml(defaultfalse— no change for existing users)charts/dify/templates/plugin-daemon-deployment.yamlthat emitsshareProcessNamespace: truewhen the flag is enabledTest plan
helm templatewith--set pluginDaemon.shareProcessNamespace=trueemitsshareProcessNamespace: trueat the correct pod-spec levelhelm templatewith defaults emits noshareProcessNamespacefield (backward compatible)kubectl patchon a live GKE cluster — OpenAI plugin subprocess stays alive;ValidateProviderCredentialssucceeds end-to-endhelm templatewith and without the flagNotes
sh -c(fragile signal/zombie handling); patching the SDK in place (has to be reapplied per-plugin-install).pluginDaemon.podSpecoverride hook — if the project prefers that direction.