Plugin daemon cannot access files served by API in mixed local/container development setup #16744

Closed
opened 2026-02-21 19:27:24 -05:00 by yindo · 4 comments
Owner

Originally created by @QuantumGhost on GitHub (Sep 4, 2025).

Originally assigned to: @QuantumGhost, @crazywoola on GitHub.

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

main

Cloud or Self Hosted

Self Hosted (Source)

Steps to reproduce

Problem Description

When running Dify in a mixed development environment (local backend + containerized plugin daemon), the plugin daemon fails to access files served by the API due to incorrect URL resolution.

Development Setup

  • Dify Backend: Running locally on host machine
  • Plugin Daemon: Running in Docker container via docker-compose

This setup is convenient for development as it allows direct backend debugging while isolating the plugin daemon.

Root Cause

The plugin daemon attempts to fetch files from the Dify backend using URLs like:

http://127.0.0.1:5001/files/e8e83bc6-e968-4f8f-a91b-1ac3b055011f/file-preview?timestamp=1756983338&nonce=68f956fefa488c98c4bd3c1af23023c9&sign=bG63w4oy0btacJcgT-mgFR1OgilLkVA_-4tfmMbTDA0%3D

Issue: The 127.0.0.1:5001 endpoint resolves to the container's localhost instead of the Docker host, causing connection failures.

Technical Details:

  • File metadata sent to the plugin daemon contains URLs generated by File.generate_url()
  • This method uses the FILES_URL configuration as the base URL
  • Since File.generate_url() is also used for external file serving, we cannot modify its behavior specifically for development scenarios

Proposed Solution

Introduce a new configuration variable (INTERNAL_FILES_URL, for example) specifically for plugin daemon file access:

1. Add INTERNAL_FILES_URL config option (e.g., http://host.docker.internal:5001 for Docker Desktop)
There is already a configuration item named INTERNAL_FILES_URL.
A configuration option named INTERNAL_FILES_URL is already available.

  1. Modify the file metadata generation logic for plugin daemon to use INTERNAL_FILES_URL when available
  2. Fall back to FILES_URL when INTERNAL_FILES_URL is not configured (maintaining backward compatibility). (This is the default behavior now.)

Environment

  • Development Setup: Mixed (local backend + containerized plugin daemon)
  • Docker: Docker Compose

Additional Context

This issue specifically affects development workflows and does not impact production deployments where all components typically run in the same network context.

✔️ Expected Behavior

Plugin daemon should successfully access files from the local Dify backend.

Actual Behavior

Plugin daemon fails to connect to 127.0.0.1:5001 as it resolves to the container's internal localhost.

Originally created by @QuantumGhost on GitHub (Sep 4, 2025). Originally assigned to: @QuantumGhost, @crazywoola on GitHub. ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version main ### Cloud or Self Hosted Self Hosted (Source) ### Steps to reproduce ### **Problem Description** When running Dify in a mixed development environment (local backend + containerized plugin daemon), the plugin daemon fails to access files served by the API due to incorrect URL resolution. ### **Development Setup** - **Dify Backend**: Running locally on host machine - **Plugin Daemon**: Running in Docker container via docker-compose This setup is convenient for development as it allows direct backend debugging while isolating the plugin daemon. ### **Root Cause** The plugin daemon attempts to fetch files from the Dify backend using URLs like: ``` http://127.0.0.1:5001/files/e8e83bc6-e968-4f8f-a91b-1ac3b055011f/file-preview?timestamp=1756983338&nonce=68f956fefa488c98c4bd3c1af23023c9&sign=bG63w4oy0btacJcgT-mgFR1OgilLkVA_-4tfmMbTDA0%3D ``` **Issue**: The `127.0.0.1:5001` endpoint resolves to the container's localhost instead of the Docker host, causing connection failures. **Technical Details**: - File metadata sent to the plugin daemon contains URLs generated by [`File.generate_url()`](api/core/file/file.py) - This method uses the `FILES_URL` configuration as the base URL - Since `File.generate_url()` is also used for external file serving, we cannot modify its behavior specifically for development scenarios ### **Proposed Solution** ~~Introduce a new configuration variable (`INTERNAL_FILES_URL`, for example) specifically for plugin daemon file access:~~ ~~1. Add `INTERNAL_FILES_URL` config option (e.g., `http://host.docker.internal:5001` for Docker Desktop) There is already a configuration item named `INTERNAL_FILES_URL`.~~ A configuration option named `INTERNAL_FILES_URL` is already available. 1. Modify the file metadata generation logic for plugin daemon to use `INTERNAL_FILES_URL` when available 2. Fall back to `FILES_URL` when `INTERNAL_FILES_URL` is not configured (maintaining backward compatibility). (This is the default behavior now.) ### **Environment** - **Development Setup**: Mixed (local backend + containerized plugin daemon) - **Docker**: Docker Compose ### **Additional Context** This issue specifically affects development workflows and does not impact production deployments where all components typically run in the same network context. ### ✔️ Expected Behavior Plugin daemon should successfully access files from the local Dify backend. ### ❌ Actual Behavior Plugin daemon fails to connect to `127.0.0.1:5001` as it resolves to the container's internal localhost.
yindo added the good first issue label 2026-02-21 19:27:24 -05:00
yindo closed this issue 2026-02-21 19:27:24 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 4, 2025):

You're right—this is a known limitation in mixed local/container setups. The plugin daemon gets file URLs based on the FILES_URL config, which points to localhost and isn't accessible from inside the container. The INTERNAL_FILES_URL config option was added to solve this, but as of now, File.generate_url and related metadata generation do not use it for plugin daemon access, so the issue persists source.

For now, you can work around this by setting FILES_URL to your host's IP or host.docker.internal in your .env and Docker Compose files. This will make the URLs resolvable from the container. For a proper fix, the code should be updated so that when generating file URLs for the plugin daemon, it uses INTERNAL_FILES_URL if set, falling back to FILES_URL otherwise. This logic is present in some helper functions but not in File.generate_url itself source.

If you want to contribute a fix, add conditional logic to File.generate_url or the file metadata generation path to use INTERNAL_FILES_URL for plugin daemon contexts. Make sure to keep backward compatibility. Also, double-check your Docker Compose environment variables: both FILES_URL and INTERNAL_FILES_URL must be set correctly for plugin output and error propagation to work source.

Let me know if you need example config snippets or guidance on patching the code!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 4, 2025): <!-- Answer --> You're right—this is a known limitation in mixed local/container setups. The plugin daemon gets file URLs based on the FILES_URL config, which points to localhost and isn't accessible from inside the container. The INTERNAL_FILES_URL config option was added to solve this, but as of now, File.generate_url and related metadata generation do not use it for plugin daemon access, so the issue persists [source](https://github.com/langgenius/dify/pull/21382). For now, you can work around this by setting FILES_URL to your host's IP or host.docker.internal in your .env and Docker Compose files. This will make the URLs resolvable from the container. For a proper fix, the code should be updated so that when generating file URLs for the plugin daemon, it uses INTERNAL_FILES_URL if set, falling back to FILES_URL otherwise. This logic is present in some helper functions but not in File.generate_url itself [source](https://github.com/langgenius/dify/pull/21382). If you want to contribute a fix, add conditional logic to File.generate_url or the file metadata generation path to use INTERNAL_FILES_URL for plugin daemon contexts. Make sure to keep backward compatibility. Also, double-check your Docker Compose environment variables: both FILES_URL and INTERNAL_FILES_URL must be set correctly for plugin output and error propagation to work [source](https://github.com/langgenius/dify-official-plugins/issues/1402#issuecomment-3146202141). Let me know if you need example config snippets or guidance on patching the code! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/32b2e815-38c5-417e-9d85-5006168b227d?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/6088a4f4-073a-43f3-b3d4-4f06fb0c05a0/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/25168)
Author
Owner
@laipz8200 commented on GitHub (Sep 11, 2025): https://github.com/langgenius/dify/blob/af7f67dc9c2c7e8fd1d60998b60d68570777bbd4/docker/.env.example#L53C15-L53C16
Author
Owner

@crazywoola commented on GitHub (Sep 18, 2025):

Image

https://github.com/langgenius/dify/blob/85cda47c70acd6e2e09f3e2fa74a413950186ffe/api/.env.example#L22-L28

- FILES_URL=http://localhost:5001
+ FILES_URL=http://host.docker.internal:5001

 # INTERNAL_FILES_URL is used for plugin daemon communication within Docker network.
 # Set this to the internal Docker service URL for proper plugin file access.
 # Example: INTERNAL_FILES_URL=http://api:5001
- INTERNAL_FILES_URL=http://127.0.0.1:5001
+ INTERNAL_FILES_URL=http://host.docker.internal:5001
@crazywoola commented on GitHub (Sep 18, 2025): ![Image](https://github.com/user-attachments/assets/23d8edd9-03c1-456a-a776-0a6580ce5b02) https://github.com/langgenius/dify/blob/85cda47c70acd6e2e09f3e2fa74a413950186ffe/api/.env.example#L22-L28 ```diff - FILES_URL=http://localhost:5001 + FILES_URL=http://host.docker.internal:5001 # INTERNAL_FILES_URL is used for plugin daemon communication within Docker network. # Set this to the internal Docker service URL for proper plugin file access. # Example: INTERNAL_FILES_URL=http://api:5001 - INTERNAL_FILES_URL=http://127.0.0.1:5001 + INTERNAL_FILES_URL=http://host.docker.internal:5001 ```
Author
Owner

@QuantumGhost commented on GitHub (Oct 15, 2025):

@crazywoola The File.to_plugin_parameter calls generate_url method, which then uses FILES_URL instead of INTERNAL_FILES_URL to generate urls passed to plugins.

In the mixed development setup, this causes the generated url to be 127.0.0.1, causing the above issue.

@QuantumGhost commented on GitHub (Oct 15, 2025): @crazywoola The [`File.to_plugin_parameter`](https://github.com/langgenius/dify/blob/main/api/core/file/models.py#L124) calls `generate_url` method, which then uses `FILES_URL` instead of `INTERNAL_FILES_URL` to generate urls passed to plugins. In the mixed development setup, this causes the generated url to be `127.0.0.1`, causing the above issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#16744