Dify カスタム Sandbox が無限ループに陥る:「Operation not permitted」を修正後、「ModuleNotFoundError」が発生し、両者は共存できない

環境情報:

  • システム: Windows 11 + WSL2 (Ubuntu 22.04)

  • デプロイ: Docker Compose ソースコードによるデプロイ

  • 要件: Sandbox 内で数理最適化コードを実行(networkx および pulp + システムレベルのソルバー glpk/cbc が必要)。

問題の説明: カスタムの Sandbox イメージを作成し、docker-compose.yml を修正しましたが、奇妙な「エラーループ」に陥っており、「依存関係が存在する」と「権限が十分である」の両方を同時に満たすことができません。

核心的な矛盾(The Loop):

  1. 状態 A:エラー “ModuleNotFoundError”

    • ライブラリが存在するようイメージを再構築しようとすると、Web インターフェースで「ライブラリが見つからない」というエラーが表示されます。

    • ただし、コンテナ内に docker exec で入って確認すると、ライブラリは存在しています。

  2. 状態 B:エラー “error: operation not permitted”

    • PuLP ソルバーの権限問題を解決するため、docker-compose.ymlsecurity_opt: seccomp:unconfined および privileged: true を設定しました。

    • 権限が有効になった(またはサービスを再起動して設定をリフレッシュした)直後、エラーは “No module named ‘networkx’” に変わります。

    • もしライブラリが見つかるように設定しても、コードが prob.solve() に到達すると再び “operation not permitted” に変わります。

私の設定:

1. Dockerfile.sandbox(以下)

FROM langgenius/dify-sandbox:latest
USER root
RUN apt-get update && apt-get install -y coinor-cbc glpk-utils

RUN pip install --no-cache-dir --default-timeout=1000 -i https://mirrors.aliyun.com/pypi/simple/ \
numpy \
pandas \
scipy

RUN pip install --no-cache-dir --default-timeout=1000 -i https://mirrors.aliyun.com/pypi/simple/ \
networkx \
pulp \
scikit-opt \
statsmodels \
scikit-learn \
scienceplots \
openpyxl

2. docker-compose.yml(権限を解放する設定)

sandbox:
   image: my-math-sandbox:local
   container_name: docker-sandbox-1
   restart: always

   privileged: true
   security_opt:
       - seccomp:unconfined
       - apparmor:unconfined
   cap_add:
       - SYS_PTRACE

確認済みの事実:

  1. イメージ構築は正常: docker run --rm -it my-math-sandbox:local python3 -c "import pulp; print('ok')" でテストしたところ、ライブラリとソルバーは正常に動作します。

  2. コンテナは実行中: docker ps で確認すると、sandbox は確かに my-math-sandbox:local イメージを読み込んでいます。

  3. Exec テストは成功: コンテナ実行中に docker exec -it docker-sandbox-1 python3 で手動でスクリプトを実行すると、完全に正常で、権限エラーもライブラリ欠損エラーも発生しません

質問の核心: なぜ Dify Web インターフェース(Go Runner) でコードを実行する環境と、私が docker exec で入った環境がこれほど異なる挙動を示すのでしょうか?

  • Dify の Runner が Python プロセスを起動する際に、Docker Compose の security_opt を無視している可能性はありますか?

  • あるいは、特権モードを有効にすると、Runner が異なるファイルシステムをマウントして、私の pip install が無効になる可能性はありますか?

どうか、この問題の調査方向をご教示ください!このループに2日間悩まされています。

@Mahu さん

こんにちは、

Dify Sandbox は Seccomp をベースにしたサンドボックス環境を提供しています。
これは Dify Sandbox サービス内に独立して実装されており、コンテナレベルの security_opt.seccomp 設定とは関係ありません。
そのため、コードブロック内で利用可能な Python モジュールや実行可能なシステムコールには制限があります。

私はすべてを徹底的にテストできていませんが、以下の情報がヒントになるかと思います。

カスタム Dockerfile

apt でパッケージを追加することは、試した通りうまくいくはずです。ただし、pip はここで効果がありませんので、Dockerfile に以下の3行を追加するだけで十分です。

FROM langgenius/dify-sandbox:latest
USER root
RUN apt-get update && apt-get install -y coinor-cbc glpk-utils

あるいは、pip のコマンドをそのまま残しておき、後で config.yamlpython_lib_path 設定を使ってシステム全体のモジュールパスを追加する方法もありますが、この方法は試していません。

Python モジュールの追加

Dify Sandbox では、コンテナ内に /dependencies/python-requirements.txt ファイルを配置すると、自動的にインストールされます。
フォーマットは標準的な requirements.txt ファイルと同じです。
pip でインストールしようとしたモジュールはすべてこのファイルに記載してください。
ホストからこのファイルをコンテナにバインドマウントすることをおすすめします。

デフォルトは空です: dify-sandbox/dependencies/python-requirements.txt at main · langgenius/dify-sandbox · GitHub

システムコールの制御

「操作が許可されていません」というエラーは、必要なシステムコールが許可されていない場合によく発生します。
Dify Sandbox の設定はコンテナ内の /conf/config.yaml ファイルで制御できます。リポジトリにはデフォルトのファイルがあります: dify/docker/volumes/sandbox/conf/config.yaml at main · langgenius/dify · GitHub

ここには allowed_syscalls キーがあり、整数の配列を渡すことで対応するシステムコールを許可できます。

...
allowed_syscalls:
  - 1
  - 2
  - 3
  # 必要なシステムコールをすべて追加
...

python-requirements.txt と同じように、このファイルもバインドマウントすることをおすすめします。
あるいは、ALLOWED_SYSCALLS 環境変数にカンマ区切りの数値リスト(例: 1,2,3)を渡すことで、同様の効果を得られる可能性があります。

Python コードに必要なシステムコールを正確に特定するのは簡単ではありませんが、FAQ にいくつかのヒントがあります: dify-sandbox/FAQ.md at main · langgenius/dify-sandbox · GitHub

もしセキュリティ上のリスクを許容できるのであれば、すべてのシステムコールを許可するという方法もあります。

代替案

設定やトラブルシューティングが複雑すぎる場合は、専用のプラグインを開発するという方法も検討できます。

プラグインを使用すれば、Seccomp の制限を受けず、必要なモジュールを自由に導入できます。

詳しくは: Dify Plugin - Dify Docs

ご参考になれば幸いです!

ひとつ忘れていました。

デフォルトでは、Dify Sandbox は /dependencies/python-requirements.txt に従って、30分ごとにPythonモジュールを再インストールします。

環境によっては、これによりメモリ使用量が継続的に増加したり、定期的にCPU使用率が高くなったりする可能性があります。
もしそういった懸念がある場合は、関連する環境変数 PYTHON_DEPS_UPDATE_INTERVAL を調整してモジュールのインストール間隔を変更することを検討してください。

詳細: There is a memory leak issue with the sandbox version 0.2.11 when the service is deployed in a containerized environment. · Issue #168 · langgenius/dify-sandbox · GitHub

コードブロックは少し制限があるため、個人的にはプラグインを自由に作成する傾向があります。
プログラミングの経験があれば、アイデアをプラグインとして実現することもそれほど難しくないと思いますので、ぜひそうしたアプローチを検討してみてください。

どうもありがとうございました。あなたの方法に従って問題を解決してみます。あなたのアイデアは私にとってとてもインスピレーションになりました。:smiley:

「いいね!」 1