mirror of
https://github.com/langgenius/dify.git
synced 2026-11-10 21:35:45 +08:00
fix(docker): honor categorized service environment overrides (#45359)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
8d812b938a
commit
53ea596fc7
75 files changed
+2793
-2045
No files matched your search
@@ -30,6 +30,9 @@ jobs:
|
||||
docker/.env.example
|
||||
docker/docker-compose-template.yaml
|
||||
docker/docker-compose.yaml
|
||||
docker/docker-compose.e2b.yaml
|
||||
docker/envs/**
|
||||
docker/tests/**
|
||||
- name: Check api inputs
|
||||
if: github.event_name != 'merge_group'
|
||||
id: api-changes
|
||||
@@ -72,6 +75,10 @@ jobs:
|
||||
cd docker
|
||||
./generate_docker_compose
|
||||
|
||||
- name: Check Docker environment overrides
|
||||
if: github.event_name != 'merge_group' && steps.docker-compose-changes.outputs.any_changed == 'true'
|
||||
run: python3 -m unittest discover -s docker/tests -p 'test_*.py'
|
||||
|
||||
- if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd api
|
||||
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
- 'docker/dify-env-sync.sh'
|
||||
- 'docker/docker-compose-template.yaml'
|
||||
- 'docker/docker-compose.yaml'
|
||||
- 'docker/envs/core-services/api.env.example'
|
||||
- 'docker/envs/core-services/api.defaults'
|
||||
- 'docker/envs/core-services/knowledge-fs.env.example'
|
||||
- 'docker/envs/core-services/knowledge-fs-unstructured-service.defaults'
|
||||
- 'docker/envs/core-services/knowledge-fs-unstructured.env.example'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import dotenv_values
|
||||
@@ -99,22 +100,58 @@ def _api_config_set() -> set[str]:
|
||||
return set(dotenv_values(REPO_ROOT / "api" / ".env.example").keys())
|
||||
|
||||
|
||||
def _docker_config_set() -> set[str]:
|
||||
docker_config_set = set(dotenv_values(REPO_ROOT / "docker" / ".env.example").keys())
|
||||
envs_dir = REPO_ROOT / "docker" / "envs"
|
||||
if envs_dir.exists():
|
||||
for env_file_path in envs_dir.rglob("*.env.example"):
|
||||
docker_config_set.update(dotenv_values(env_file_path).keys())
|
||||
def _docker_config_set(docker_dir: Path) -> set[str]:
|
||||
"""Return keys documented in readable Docker templates, excluding local overrides.
|
||||
|
||||
Include assignments, commented assignments, and explicit root .env instructions.
|
||||
The root .env.example must exist; read failures propagate without changing any files.
|
||||
"""
|
||||
envs_dir = docker_dir / "envs"
|
||||
env_files = [docker_dir / ".env.example", *envs_dir.rglob("*.env.example"), *envs_dir.rglob("*.defaults")]
|
||||
docker_config_set: set[str] = set()
|
||||
for env_file_path in env_files:
|
||||
content = env_file_path.read_text()
|
||||
docker_config_set.update(dotenv_values(env_file_path, interpolate=False).keys())
|
||||
docker_config_set.update(re.findall(r"(?m)^[ \t]*#[ \t]*([A-Z_][A-Z0-9_]*)=", content))
|
||||
docker_config_set.update(re.findall(r"(?m)^# Set ([A-Z_][A-Z0-9_]*) in docker/\.env\b", content))
|
||||
return docker_config_set
|
||||
|
||||
|
||||
def test_docker_config_set_includes_documented_keys_only(tmp_path: Path) -> None:
|
||||
"""Given templates and local overrides, collect only keys documented in the templates."""
|
||||
envs_dir = tmp_path / "envs" / "core-services"
|
||||
envs_dir.mkdir(parents=True)
|
||||
(tmp_path / ".env.example").write_text("ROOT_KEY=value\n# ROOT_OPTIONAL=\n")
|
||||
(envs_dir / "service.defaults").write_text(
|
||||
"DEFAULT_KEY=${ROOT_KEY:-fallback}\n# OPTIONAL_KEY=\n # INDENTED_KEY=value\n"
|
||||
"# Set COMPOSE_PORT in docker/.env; Compose needs it before loading service files.\n"
|
||||
"# Prose with NOT_A_KEY=value\n# NO_ASSIGNMENT\n"
|
||||
)
|
||||
(envs_dir / "provider.env.example").write_text("PROVIDER_KEY=value\n# PROVIDER_OPTIONAL=value\n")
|
||||
(tmp_path / ".env").write_text("LOCAL_ROOT_KEY=private\n")
|
||||
(envs_dir / "service.env").write_text("LOCAL_SERVICE_KEY=private\n")
|
||||
|
||||
assert _docker_config_set(tmp_path) == {
|
||||
"ROOT_KEY",
|
||||
"ROOT_OPTIONAL",
|
||||
"DEFAULT_KEY",
|
||||
"OPTIONAL_KEY",
|
||||
"INDENTED_KEY",
|
||||
"COMPOSE_PORT",
|
||||
"PROVIDER_KEY",
|
||||
"PROVIDER_OPTIONAL",
|
||||
}
|
||||
|
||||
|
||||
def test_api_env_keys_exist_in_docker_env_examples() -> None:
|
||||
diff = _api_config_set() - _docker_config_set() - BASE_API_AND_DOCKER_CONFIG_SET_DIFF
|
||||
"""Require every non-exempt API setting to remain documented in Docker templates."""
|
||||
diff = _api_config_set() - _docker_config_set(REPO_ROOT / "docker") - BASE_API_AND_DOCKER_CONFIG_SET_DIFF
|
||||
|
||||
assert not diff, f"API and Docker config sets are different with keys: {sorted(diff)}"
|
||||
|
||||
|
||||
def test_api_env_keys_exist_in_docker_compose_env_examples() -> None:
|
||||
diff = _api_config_set() - _docker_config_set() - BASE_API_AND_DOCKER_COMPOSE_CONFIG_SET_DIFF
|
||||
"""Require every non-exempt API setting to remain documented for Docker Compose."""
|
||||
diff = _api_config_set() - _docker_config_set(REPO_ROOT / "docker") - BASE_API_AND_DOCKER_COMPOSE_CONFIG_SET_DIFF
|
||||
|
||||
assert not diff, f"API and Docker Compose config sets are different with keys: {sorted(diff)}"
|
||||
@@ -25,10 +25,8 @@ def test_binding_file_download_timeout_rejects_non_positive_values() -> None:
|
||||
|
||||
def test_binding_file_timeout_docker_settings_use_their_service_env_files() -> None:
|
||||
root_env_example = (_REPOSITORY_ROOT / "docker/.env.example").read_text(encoding="utf-8")
|
||||
api_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/api.env.example").read_text(encoding="utf-8")
|
||||
agent_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/dify-agent.env.example").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
api_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/api.defaults").read_text(encoding="utf-8")
|
||||
agent_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/dify-agent.defaults").read_text(encoding="utf-8")
|
||||
compose_template = (_REPOSITORY_ROOT / "docker/docker-compose-template.yaml").read_text(encoding="utf-8")
|
||||
|
||||
assert f"{_API_TIMEOUT_ENV}=" not in root_env_example
|
||||
|
||||
@@ -122,7 +122,7 @@ def test_disabled_knowledge_fs_config_allows_partial_connection() -> None:
|
||||
|
||||
def test_knowledge_fs_docker_config_is_not_shadowed_by_root_env() -> None:
|
||||
root_env_example = (_REPOSITORY_ROOT / "docker/.env.example").read_text(encoding="utf-8")
|
||||
api_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/api.env.example").read_text(encoding="utf-8")
|
||||
api_env_example = (_REPOSITORY_ROOT / "docker/envs/core-services/api.defaults").read_text(encoding="utf-8")
|
||||
|
||||
for variable in _KNOWLEDGE_FS_DOCKER_VARIABLES:
|
||||
assert f"{variable}=" not in root_env_example
|
||||
|
||||
@@ -58,7 +58,7 @@ DIFY_AGENT_E2B_ACTIVE_TIMEOUT_SECONDS=3600
|
||||
DIFY_AGENT_E2B_SHELLCTL_PORT=5004
|
||||
|
||||
# Minimal OpenShell configuration subset for local debugging.
|
||||
# Full configuration reference: docker/envs/core-services/dify-agent.env.example
|
||||
# Full configuration reference: docker/envs/core-services/dify-agent.defaults
|
||||
DIFY_AGENT_OPENSHELL_GATEWAY_ENDPOINT=localhost:17670
|
||||
DIFY_AGENT_OPENSHELL_TLS_CA_PATH=${HOME}/.config/openshell/gateways/openshell/mtls/ca.crt
|
||||
DIFY_AGENT_OPENSHELL_TLS_CLIENT_CERT_PATH=${HOME}/.config/openshell/gateways/openshell/mtls/tls.crt
|
||||
|
||||
@@ -153,7 +153,7 @@ spec:
|
||||
```
|
||||
|
||||
Configure the backend in `docker/.env`. The full `DIFY_AGENT_OPENSHELL_*`
|
||||
variable reference lives in `docker/envs/core-services/dify-agent.env.example`;
|
||||
variable reference lives in `docker/envs/core-services/dify-agent.defaults`;
|
||||
values may also be set in the `envs/core-services/dify-agent.env` env_file,
|
||||
but `docker/.env` is loaded last into `agent_backend` and overrides it. These
|
||||
lines are `.env` file content, not shell commands — values are taken verbatim,
|
||||
|
||||
+6
-1
@@ -1,10 +1,15 @@
|
||||
# Only settings requiring manual configuration belong in this file.
|
||||
# Requires Docker Compose v2.35.0+ for .env override precedence.
|
||||
# Application and Docker defaults are loaded automatically; do not repeat them here.
|
||||
# Copy this file to .env, then select the services for your deployment.
|
||||
# Optional overrides and provider settings are documented in envs/**/*.env.example.
|
||||
# Optional overrides and provider settings are documented in envs/.
|
||||
# Values in .env take precedence over the matching envs/*.env files.
|
||||
|
||||
# Compose requires an explicit selection of the bundled database, vector store,
|
||||
# and websocket service. Match these profiles to your DB_TYPE and VECTOR_STORE
|
||||
# overrides when using different providers; omit services hosted externally.
|
||||
COMPOSE_PROFILES=weaviate,postgresql,collaboration
|
||||
|
||||
# Required for the default local Agent sandbox. Generate with: openssl rand -hex 32
|
||||
# Both the Agent backend and shellctl use this shared secret.
|
||||
DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN=
|
||||
+362
-171
@@ -1,103 +1,299 @@
|
||||
# Docker deployment
|
||||
|
||||
Run Dify with Docker Compose. Configuration templates live in `.env.example` and `envs/`; local overrides belong in `.env`.
|
||||
Run Dify with Docker Compose. For the default deployment, copy `.env.example` to
|
||||
`.env`, fill in the required token, and start the services. Defaults for the API,
|
||||
workers, and supporting services load automatically; additional files are optional.
|
||||
|
||||
## How to Deploy Dify with `docker-compose.yaml`
|
||||
- [Start Dify](#start-dify)
|
||||
- [Configure Dify](#configure-dify)
|
||||
- [Troubleshoot setup and configuration](#troubleshoot-setup-and-configuration)
|
||||
- [Review configuration after an upgrade](#review-configuration-after-an-upgrade)
|
||||
- [Run middleware for development](#run-middleware-for-development)
|
||||
- [Configure HTTPS and telemetry](#configure-https-and-telemetry)
|
||||
- [Configure worker queues and webhooks](#configure-worker-queues-and-webhooks)
|
||||
- [Enable the KnowledgeFS integration](#enable-the-knowledgefs-integration)
|
||||
- [Configure client IP and trusted proxies](#client-ip-and-trusted-proxies)
|
||||
|
||||
## Start Dify
|
||||
|
||||
Before you begin, install Docker with a running daemon, Docker Compose **v2.35.0 or
|
||||
later**, and OpenSSL to generate the sandbox token. Check your Compose version with
|
||||
`docker compose version`. Version 2.35.0 or later is required for root `.env`
|
||||
overrides to take precedence when Compose resolves service defaults.
|
||||
|
||||
For an existing deployment, edit your current `.env` instead of replacing it.
|
||||
For a new deployment, follow these steps:
|
||||
|
||||
1. From the repository root, enter the Docker directory and copy the template:
|
||||
|
||||
1. **Prerequisites**: Ensure Docker and Docker Compose v2.24.0 or later are installed on your system.
|
||||
2. **Environment Setup**:
|
||||
- Navigate to the `docker` directory.
|
||||
- Copy `.env.example` to `.env`.
|
||||
- Select the bundled services through `COMPOSE_PROFILES`. Add overrides to `.env` only when needed. Copy optional files from `envs/` without the `.example` suffix when you need advanced settings.
|
||||
- **Optional (for advanced deployments)**:
|
||||
If you maintain a full `.env` file copied from `.env.example`, you may use the environment synchronization tool to keep it aligned with the latest `.env.example` updates while preserving your custom settings.
|
||||
See the [Environment Variables Synchronization](#environment-variables-synchronization) section below.
|
||||
3. **Running the Services**:
|
||||
- Execute `docker compose up -d` from the `docker` directory to start the services.
|
||||
- To specify a vector database, set the `VECTOR_STORE` variable in your `.env` file to your desired vector database service, such as `milvus`, `weaviate`, or `opensearch`, and select the matching service in `COMPOSE_PROFILES`. See `envs/vectorstores/` for the full list of supported options.
|
||||
```bash
|
||||
cd docker
|
||||
cp .env.example .env
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. **SSL Certificate Setup**:
|
||||
- Refer to [the Certbot guide](certbot/README.md) to set up SSL certificates using Certbot.
|
||||
5. **OpenTelemetry Collector Setup**:
|
||||
- Copy `envs/core-services/shared.env.example` to `envs/core-services/shared.env`.
|
||||
- Set `ENABLE_OTEL=true` and configure `OTLP_BASE_ENDPOINT`. Tune the other `OTEL_*` knobs in the same file if needed.
|
||||
Unless noted otherwise, run commands below from `docker/`.
|
||||
|
||||
## KnowledgeFS Integration Service
|
||||
2. Generate a token:
|
||||
|
||||
The optional `knowledge-fs` Compose profile starts the internal KnowledgeFS API service and the
|
||||
dedicated Dataset upgrade worker. The API service publishes no host port and has no nginx route.
|
||||
Model, datasource, and object-storage calls go through Dify's inner API.
|
||||
Dify resolves active Workspace/plugin configuration and remains the only owner of physical
|
||||
storage credentials. `KNOWLEDGE_FS_ENABLED` remains `false`, so starting the container does not
|
||||
enable product traffic.
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
Copy and fill the dedicated service configuration before enabling KnowledgeFS traffic. The default
|
||||
image is the CI-published deployment-branch image; set `KNOWLEDGE_FS_API_IMAGE` to pin another tag
|
||||
or immutable SHA tag. If the image repository is private, authenticate the deployment host with
|
||||
`docker login` before pulling:
|
||||
Open `.env` and paste the output as the value of
|
||||
`DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN`. Keep
|
||||
`COMPOSE_PROFILES=weaviate,postgresql,collaboration` for the default deployment.
|
||||
No other configuration files are required.
|
||||
|
||||
```bash
|
||||
cp envs/core-services/knowledge-fs.env.example envs/core-services/knowledge-fs.env
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured config
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured pull knowledge_fs knowledge_fs_unstructured
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured up -d
|
||||
3. Start the services and check their status:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
docker compose ps --all
|
||||
```
|
||||
|
||||
Wait for the long-running services to start and their health checks to pass.
|
||||
The one-time `init_permissions` service is expected to exit with code `0`.
|
||||
|
||||
4. Open [http://localhost/install](http://localhost/install) and complete the
|
||||
initial setup. If you changed the published HTTP port, use that port in the URL.
|
||||
|
||||
Before using this deployment in production, replace the bundled credentials using
|
||||
[the security template](envs/security.env.example) and the matching service files,
|
||||
and configure [HTTPS](#configure-https-and-telemetry) and
|
||||
[trusted proxies](#client-ip-and-trusted-proxies).
|
||||
|
||||
## Configure Dify
|
||||
|
||||
### Choose the configuration file
|
||||
|
||||
| File | Purpose | Loaded directly? |
|
||||
| --- | --- | --- |
|
||||
| `.env.example` | Minimal template for required deployment inputs | No; copy it to `.env` |
|
||||
| `.env` | Deployment inputs and explicit overrides, including Compose settings | Yes |
|
||||
| `envs/**/*.defaults` | Tracked defaults for the matching services | Yes, automatically |
|
||||
| `envs/**/*.env` | Optional service or provider overrides | Yes, when the matching service references the file |
|
||||
| `envs/**/*.env.example` | Templates for optional application and provider settings | No; remove only `.example` when copying |
|
||||
|
||||
Keep settings with usable defaults out of the root `.env.example`. To customize a
|
||||
service, copy its `.defaults` file to the override path named in its comments,
|
||||
usually replacing `.defaults` with `.env` in the same directory. Edit the copy,
|
||||
or the existing `.env` if one is already present. Uncomment only the optional
|
||||
assignments you want to change; leave unused empty values and placeholders
|
||||
commented. For an optional `.env.example` template, review its comments and fill
|
||||
in the settings before use.
|
||||
|
||||
Find settings in:
|
||||
|
||||
- [Core services](envs/core-services/): API, workers, web, plugin daemon, and
|
||||
sandboxes. [shared.defaults](envs/core-services/shared.defaults) contains the
|
||||
common API, worker, and Beat settings, grouped by function. API process options
|
||||
live in `api.defaults`; worker autoscaling lives in `worker.defaults`.
|
||||
- [Databases](envs/databases/): PostgreSQL, MySQL, and Redis.
|
||||
- [Vector stores](envs/vectorstores/): bundled and external vector databases,
|
||||
including their API/worker client settings. Providers without a dedicated
|
||||
template are documented in `shared.defaults`.
|
||||
- [Infrastructure](envs/infrastructure/): nginx, Certbot, proxies, and supporting services.
|
||||
|
||||
### Change a service setting
|
||||
|
||||
For example, to set nginx's upload limit to `200M`:
|
||||
|
||||
1. Create the optional override file if it does not already exist:
|
||||
|
||||
```bash
|
||||
cp envs/infrastructure/nginx.defaults envs/infrastructure/nginx.env
|
||||
```
|
||||
|
||||
2. In `envs/infrastructure/nginx.env`, replace the input setting with:
|
||||
|
||||
```dotenv
|
||||
NGINX_CLIENT_MAX_BODY_SIZE=200M
|
||||
```
|
||||
|
||||
Leave expressions under `Container variable mappings` unchanged. They translate
|
||||
input names such as `SANDBOX_WORKER_TIMEOUT` into the container's `WORKER_TIMEOUT`.
|
||||
|
||||
3. Apply the change and inspect nginx's active configuration:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
docker compose exec -T nginx nginx -T 2>&1 | grep client_max_body_size
|
||||
```
|
||||
|
||||
The output should contain `client_max_body_size 200M;`.
|
||||
|
||||
Use `docker compose up -d` after editing configuration files. Compose recreates
|
||||
containers whose configuration changed. `docker compose restart` does not reload
|
||||
environment variables. No extra `--env-file` option is needed for this deployment.
|
||||
|
||||
### Change a published port or another Compose setting
|
||||
|
||||
Put settings consumed by Compose in root `.env`: `COMPOSE_PROFILES`, published
|
||||
ports, volume paths, resource limits, and health-check intervals. Service env
|
||||
files cannot change those parts of the Compose model.
|
||||
|
||||
For example, add or update this line in `.env` to use HTTP port `8080`:
|
||||
|
||||
```dotenv
|
||||
EXPOSE_NGINX_PORT=8080
|
||||
```
|
||||
|
||||
The service env file intentionally contains only operator-owned inputs: the dedicated database,
|
||||
durable compilation switch, Capability v2 public verification material, and optional Unstructured
|
||||
endpoint. Compose injects the Dify inner API connection and integrated mode. KnowledgeFS stores
|
||||
objects below an internal namespace in Dify's configured `STORAGE_TYPE`; do not duplicate Dify's
|
||||
bucket, endpoint, or provider credentials in `knowledge-fs.env`. Feature-specific rollout flags
|
||||
and capacity tunables should be added only when deliberately overriding their safe runtime
|
||||
defaults.
|
||||
Run `docker compose up -d`, then open
|
||||
[http://localhost:8080/install](http://localhost:8080/install).
|
||||
Use root `.env` for values shared with the isolated local Agent sandbox, including
|
||||
its authentication token.
|
||||
|
||||
The optional `knowledge-fs-unstructured` profile starts one isolated parser service named
|
||||
`knowledge_fs_unstructured` for every KnowledgeFS remote format. Its tracked
|
||||
`knowledge-fs-unstructured-service.defaults` additionally enables bounded page parallelism for
|
||||
PDFs and a 25-million-pixel pre-allocation limit per page at the pinned 350 DPI; an optional copied
|
||||
`knowledge-fs-unstructured.env` can override those service values. Do not raise the DPI or pixel
|
||||
limit, or disable the guard: the KnowledgeFS client estimates page rasters at 350 DPI and rejects
|
||||
oversized or unverifiable page geometry before sending it to the parser. Oversized pages need
|
||||
smaller page dimensions or tiling before import; reducing compressed file size alone does not
|
||||
help. Existing installations need the new KnowledgeFS image and a recreated parser service to
|
||||
activate both guards. The
|
||||
existing `unstructured` profile remains unchanged for Dify's legacy ETL, so KnowledgeFS tuning
|
||||
cannot alter its PDF or Office parsing behavior. The copied
|
||||
`knowledge-fs.env` pairs every PDF and structurally/byte-heavy remote document with the longer
|
||||
deadline and narrower admission gate; ordinary formats retain two concurrent requests and a
|
||||
600-second timeout, while heavy work uses one concurrent request and a 2,400-second timeout. The
|
||||
remote input cap defaults to 15 MiB so the parser accepts the complete product upload envelope. The
|
||||
legacy `UNSTRUCTURED_PDF_*` names remain lower-precedence compatibility aliases. The required
|
||||
defaults file deliberately does not end
|
||||
in `.env`, so it remains tracked and a clean checkout can validate the profile; files ending in
|
||||
`.env.example` are copy-only templates and are never loaded as runtime configuration. The isolated
|
||||
service is available to KnowledgeFS at `http://knowledge_fs_unstructured:8000`; it does not publish
|
||||
a host port.
|
||||
### Change shared plugin credentials
|
||||
|
||||
The KnowledgeFS API image includes Poppler and enables its `pdftoppm` PDF image rasterizer with
|
||||
bounded defaults (144 DPI, 48 DPI thumbnails, a 30-second timeout, at most 500 assets per document,
|
||||
and two concurrent Poppler page batches per replica). Canonical settings live in the dedicated
|
||||
`knowledge-fs.env`; whitelisted `DIFY_ROOT_*_OVERRIDE` proxies let explicitly set values in
|
||||
`docker/.env` take precedence without injecting the complete root environment. When a root value
|
||||
is unset, the service env or image default remains authoritative. Set
|
||||
`KNOWLEDGE_PDF_RASTERIZER=off` in either operator env as an emergency or low-resource kill switch. Existing
|
||||
documents whose parse artifacts lack image asset references must be ingested again after rollout.
|
||||
Set both shared plugin credentials in root `.env`, so every service receives the
|
||||
same values:
|
||||
|
||||
Use a dedicated KnowledgeFS database. Do not point `DATABASE_URL` at Dify's application database,
|
||||
reuse Dataset/Document tables, or run a data migration as part of this service. KnowledgeFS
|
||||
migrations remain a separate controlled operator step. The selected Dify storage backend must
|
||||
support recursive `scan`; the currently verified paths are S3 and OpenDAL/local.
|
||||
| Root `.env` setting | Used by |
|
||||
| --- | --- |
|
||||
| `PLUGIN_DAEMON_KEY` | Plugin daemon authentication and its API, worker, and Agent clients |
|
||||
| `PLUGIN_DIFY_INNER_API_KEY` | API inner-endpoint authentication and its plugin daemon, worker, Agent, and KnowledgeFS clients |
|
||||
|
||||
The production entrypoint supports the explicitly selected Capability v2 verifier and accepts only
|
||||
public JWKS material. The `knowledge_fs` container can still return `200` from
|
||||
`/health` while `/ready` returns `503` when the verifier or another durable dependency is missing;
|
||||
this is intentional fail-closed behavior. Do not add a proxy route, set
|
||||
`KNOWLEDGE_FS_ENABLED=true`, or send product traffic until readiness returns `200` and the migration
|
||||
and per-Workspace cutover gates are complete.
|
||||
Generate a separate value for each key with `openssl rand -hex 32`, then add the two
|
||||
assignments to `.env`. If you previously set these keys in a service `.env` file,
|
||||
move them to root `.env`. Leave the derived container key expressions unchanged
|
||||
when copying service defaults, including the Agent's derived key expressions.
|
||||
Editing only `plugin-daemon.env`, `api.env`, or `worker.env` does not update every
|
||||
consumer and can cause HTTP 401 responses.
|
||||
|
||||
Run `docker compose up -d` to apply the credentials to all affected services.
|
||||
These optional overrides do not need to be added to `.env.example`.
|
||||
|
||||
### Select a database or vector store
|
||||
|
||||
Set `DB_TYPE` or `VECTOR_STORE` and the provider's connection settings in the
|
||||
appropriate override file. In root `.env`, update `COMPOSE_PROFILES` to select the
|
||||
matching bundled services. Omit a service's profile when that service runs
|
||||
externally. Starting a different database does not migrate existing data.
|
||||
|
||||
For example, the default deployment selects PostgreSQL and Weaviate with
|
||||
`COMPOSE_PROFILES=weaviate,postgresql,collaboration`. The `collaboration` profile
|
||||
starts the WebSocket API. See the [database](envs/databases/) and
|
||||
[vector store](envs/vectorstores/) files for provider-specific settings.
|
||||
|
||||
### Understand which value takes effect
|
||||
|
||||
For settings loaded through these env files, precedence is:
|
||||
|
||||
1. Root `.env` overrides.
|
||||
2. Optional service `.env` overrides.
|
||||
3. Tracked `.defaults` values, followed by application defaults for unset settings.
|
||||
|
||||
Shell variables take precedence when Compose interpolates `${...}` expressions.
|
||||
An explicit Compose `environment` entry also takes precedence over service env
|
||||
files; [trusted-proxy settings](#client-ip-and-trusted-proxies) are one example.
|
||||
The [KnowledgeFS section](#enable-the-knowledgefs-integration) describes its
|
||||
restricted root overrides separately.
|
||||
|
||||
The API, workers, and plugin daemon also read the database and Redis override
|
||||
files, so shared connection settings reach both the bundled server and its clients.
|
||||
Changing a PostgreSQL or MySQL initialization password does not rotate credentials
|
||||
in an existing database; use the database's credential-rotation procedure as well.
|
||||
|
||||
## Troubleshoot setup and configuration
|
||||
|
||||
Validate the Compose configuration and inspect the affected services:
|
||||
|
||||
```bash
|
||||
docker compose config --quiet
|
||||
docker compose ps --all
|
||||
docker compose logs --tail=100 api worker nginx
|
||||
```
|
||||
|
||||
Replace the service names in the logs command with the service you are diagnosing.
|
||||
A successful `config --quiet` produces no output; it validates the Compose model,
|
||||
not application readiness.
|
||||
|
||||
| Symptom | What to check |
|
||||
| --- | --- |
|
||||
| Editing a template has no effect | Copy `.env.example` to `.env`, or a service template to its documented `.env` path. Templates ending in `.example` are not loaded. |
|
||||
| A service still uses its old value | Run `docker compose up -d`. Check for a higher-priority value in root `.env`, the shell, or an explicit Compose `environment` entry. |
|
||||
| A port or profile change has no effect | Put the setting in root `.env`; these settings cannot be supplied through a service env file. |
|
||||
| Service overrides resolve unexpectedly | Check that Docker Compose is v2.35.0 or later and that container-variable mapping expressions are intact. |
|
||||
| Python sandbox code returns `operation not permitted` | Check the network-setting note in [sandbox.defaults](envs/core-services/sandbox.defaults). On sandbox 0.2.15/ARM64, requests with networking disabled can trigger a runtime syscall restriction. |
|
||||
|
||||
## Review configuration after an upgrade
|
||||
|
||||
Review the new root `.env.example` for required deployment inputs and the matching
|
||||
`.defaults` files for changed service defaults. Preserve your existing `.env`
|
||||
files; a copied service file can pin values from an older release.
|
||||
|
||||
Bundled service templates now use the `.defaults` extension. Existing service
|
||||
`.env` paths still work. Root `.env.example` remains the only required starting
|
||||
template, and the Compose generator creates only a missing root `.env`.
|
||||
|
||||
The shared application reference is now consolidated in
|
||||
[shared.defaults](envs/core-services/shared.defaults). Existing `shared.env`
|
||||
and other override paths still work; do not replace or rename your local files.
|
||||
New customizations use the matching template listed above. Root `.env` retains
|
||||
precedence, including for settings that have moved to a provider template.
|
||||
|
||||
Review accidental empty assignments left by older template copies. For example,
|
||||
`CELERY_WORKER_AMOUNT=` overrides the Docker default of `4` and lets the worker
|
||||
entrypoint fall back to `1`. Remove or comment out that assignment to restore
|
||||
the Docker default. Likewise, remove accidental empty `SERVER_WORKER_CLASS=`
|
||||
or `GUNICORN_TIMEOUT=` entries to restore `gevent` and `360`. Keep intentional
|
||||
overrides; the configuration loader does not rewrite or discard them.
|
||||
|
||||
To merge new root-template keys into an existing `.env`, optionally run:
|
||||
|
||||
```bash
|
||||
bash dify-env-sync.sh
|
||||
```
|
||||
|
||||
The script backs up `.env` to `env-backup/.env.backup_<timestamp>`, adds missing
|
||||
keys from `.env.example`, preserves existing values and extra local overrides,
|
||||
and reports differences for review. It does not synchronize the files in `envs/`.
|
||||
Review the resulting settings before running `docker compose up -d`.
|
||||
|
||||
## Run middleware for development
|
||||
|
||||
Use `docker-compose.middleware.yaml` when running the application from source and
|
||||
you need its supporting services in Docker.
|
||||
|
||||
1. Create `middleware.env` if it does not exist:
|
||||
|
||||
```bash
|
||||
cp envs/middleware.env.example middleware.env
|
||||
```
|
||||
|
||||
2. Edit database and other middleware settings, then start the services:
|
||||
|
||||
```bash
|
||||
docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d
|
||||
```
|
||||
|
||||
This separate workflow requires `--env-file middleware.env`. The template defines
|
||||
`COMPOSE_PROFILES=${DB_TYPE:-postgresql},weaviate`, which selects the database and
|
||||
Weaviate. Update that value if you need different profiles.
|
||||
|
||||
## Configure HTTPS and telemetry
|
||||
|
||||
For HTTPS certificates, follow the [Certbot guide](certbot/README.md).
|
||||
|
||||
For OpenTelemetry, create `envs/core-services/shared.env` from `shared.defaults`
|
||||
if it does not exist. Uncomment `ENABLE_OTEL` and set it to `true`; uncomment
|
||||
`OTLP_BASE_ENDPOINT` and set it to your collector's endpoint, reachable from
|
||||
the API and worker containers. The same file documents optional `OTEL_*`
|
||||
tuning. Apply the changes with `docker compose up -d`.
|
||||
|
||||
## Configure worker queues and webhooks
|
||||
|
||||
Custom worker queue lists set through `CELERY_QUEUES` or `CELERY_WORKER_QUEUES` must include
|
||||
`human_input_delivery` to process durable Human Input IM inbox events and recover
|
||||
unconfirmed Human Input v2 notifications, and
|
||||
`human_input_contact_sync` to process manual IM Contact directory synchronization.
|
||||
|
||||
Human Input IM channels in `WEBHOOK` mode build their Callback URL from `TRIGGER_URL`.
|
||||
Set it to the externally reachable HTTPS origin of the API when configuring a remote
|
||||
deployment. A localhost value is only suitable for local development. Reverse proxies
|
||||
must forward `/callbacks/human-input/v2/im/` to the API and preserve the request path,
|
||||
body, and provider signature headers. Copy the channel's Callback URL into the
|
||||
provider's interaction configuration after changing the public origin.
|
||||
|
||||
### Ops tracing rolling upgrades
|
||||
|
||||
@@ -111,7 +307,87 @@ retry tasks finish. To return to `ops_trace`, first remove old workers, have new
|
||||
both queues, then change `OPS_TRACE_QUEUE` on all new processes and drain `ops_trace_v2` before
|
||||
removing its consumers. See the [complete rollout sequence](../api/providers/trace/README.md#rolling-upgrade-from-the-previous-pipeline).
|
||||
|
||||
### KnowledgeFS lifecycle and upgrade workers
|
||||
## Enable the KnowledgeFS integration
|
||||
|
||||
The optional `knowledge-fs` Compose profile starts the internal KnowledgeFS API service and the
|
||||
dedicated Dataset upgrade worker. The API service publishes no host port and has no nginx route.
|
||||
Model, datasource, and object-storage calls go through Dify's inner API.
|
||||
Dify resolves active Workspace/plugin configuration and remains the only owner of physical
|
||||
storage credentials. `KNOWLEDGE_FS_ENABLED` remains `false`, so starting the container does not
|
||||
enable product traffic.
|
||||
|
||||
Copy the dedicated service template if the local file does not already exist:
|
||||
|
||||
```bash
|
||||
cp envs/core-services/knowledge-fs.env.example envs/core-services/knowledge-fs.env
|
||||
```
|
||||
|
||||
Fill in the operator-owned inputs described in `knowledge-fs.env` before starting
|
||||
the services. The default image is the CI-published deployment-branch image; set
|
||||
`KNOWLEDGE_FS_API_IMAGE` to pin another tag or immutable SHA tag. If the image
|
||||
repository is private, authenticate with `docker login` before pulling:
|
||||
|
||||
```bash
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured config --quiet
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured pull knowledge_fs knowledge_fs_unstructured
|
||||
docker compose --profile knowledge-fs --profile knowledge-fs-unstructured up -d
|
||||
```
|
||||
|
||||
The service env file intentionally contains only operator-owned inputs: the dedicated database,
|
||||
durable compilation switch, Capability v2 public verification material, and optional Unstructured
|
||||
endpoint. Compose injects the Dify inner API connection and integrated mode. KnowledgeFS stores
|
||||
objects below an internal namespace in Dify's configured `STORAGE_TYPE`; do not duplicate Dify's
|
||||
bucket, endpoint, or provider credentials in `knowledge-fs.env`. Feature-specific rollout flags
|
||||
and capacity tunables should be added only when deliberately overriding their safe runtime
|
||||
defaults.
|
||||
|
||||
### Configure document parsing
|
||||
|
||||
The optional `knowledge-fs-unstructured` profile starts one isolated parser service named
|
||||
`knowledge_fs_unstructured` for every KnowledgeFS remote format. Its tracked
|
||||
`knowledge-fs-unstructured-service.defaults` additionally enables bounded page parallelism for
|
||||
PDFs and a 25-million-pixel pre-allocation limit per page at the pinned 350 DPI; an optional copied
|
||||
`knowledge-fs-unstructured.env` can override those service values. Do not raise the DPI or pixel
|
||||
limit, or disable the guard: the KnowledgeFS client estimates page rasters at 350 DPI and rejects
|
||||
oversized or unverifiable page geometry before sending it to the parser. Oversized pages need
|
||||
smaller page dimensions or tiling before import; reducing compressed file size alone does not
|
||||
help. Existing installations need the new KnowledgeFS image and a recreated parser service to
|
||||
activate both guards. The existing `unstructured` profile remains unchanged for Dify's legacy
|
||||
ETL, so KnowledgeFS tuning cannot alter its PDF or Office parsing behavior. The copied
|
||||
`knowledge-fs.env` pairs every PDF and structurally/byte-heavy remote document with the longer
|
||||
deadline and narrower admission gate; ordinary formats retain two concurrent requests and a
|
||||
600-second timeout, while heavy work uses one concurrent request and a 2,400-second timeout. The
|
||||
remote input cap defaults to 15 MiB so the parser accepts the complete product upload envelope. The
|
||||
legacy `UNSTRUCTURED_PDF_*` names remain lower-precedence compatibility aliases. The isolated
|
||||
service is available to KnowledgeFS at `http://knowledge_fs_unstructured:8000`; it does not
|
||||
publish a host port.
|
||||
|
||||
### Configure PDF image rendering
|
||||
|
||||
The KnowledgeFS API image includes Poppler and enables its `pdftoppm` PDF image rasterizer with
|
||||
bounded defaults (144 DPI, 48 DPI thumbnails, a 30-second timeout, at most 500 assets per document,
|
||||
and two concurrent Poppler page batches per replica). Canonical settings live in the dedicated
|
||||
`knowledge-fs.env`; whitelisted `DIFY_ROOT_*_OVERRIDE` proxies let explicitly set values in
|
||||
`docker/.env` take precedence without injecting the complete root environment. When a root value
|
||||
is unset, the service env or image default remains authoritative. Set
|
||||
`KNOWLEDGE_PDF_RASTERIZER=off` in either operator env as an emergency or low-resource kill switch. Existing
|
||||
documents whose parse artifacts lack image asset references must be ingested again after rollout.
|
||||
|
||||
### Check storage and readiness before enabling traffic
|
||||
|
||||
Use a dedicated KnowledgeFS database. Do not point `DATABASE_URL` at Dify's application database,
|
||||
reuse Dataset/Document tables, or run a data migration as part of this service. KnowledgeFS
|
||||
migrations remain a separate controlled operator step. The selected Dify storage backend must
|
||||
support recursive `scan`; the currently verified paths are S3 and OpenDAL/local.
|
||||
|
||||
The production entrypoint supports the explicitly selected Capability v2 verifier and accepts only
|
||||
public JWKS material. The `knowledge_fs` container can still return `200` from
|
||||
`/health` while `/ready` returns `503` when the verifier or another durable dependency is missing;
|
||||
this is intentional fail-closed behavior. Do not add a proxy route, set
|
||||
`KNOWLEDGE_FS_ENABLED=true`, or send product traffic until readiness returns `200` and the migration
|
||||
and per-Workspace cutover gates are complete.
|
||||
|
||||
### Run lifecycle and upgrade workers
|
||||
|
||||
The standard Dify worker consumes `knowledge_fs_lifecycle` for provisioning, deletion, initial
|
||||
source imports, and staged-upload cleanup. Deployments overriding `CELERY_QUEUES` or
|
||||
@@ -120,8 +396,9 @@ on the API, workers, and Beat before creating spaces.
|
||||
|
||||
Classic Dataset upgrades use the separate `worker_knowledge_fs_upgrade` service. It starts with
|
||||
the `knowledge-fs` Compose profile, so enable that profile before submitting an upgrade. This
|
||||
worker must use `CELERY_WORKER_POOL=prefork`; local development uses
|
||||
`./dev/start-worker --queues knowledge_fs_upgrade --pool prefork`. Each checkpoint has a 570-second
|
||||
worker must use `CELERY_WORKER_POOL=prefork`; for local development, run
|
||||
`./dev/start-worker --queues knowledge_fs_upgrade --pool prefork` from the repository root.
|
||||
Each checkpoint has a 570-second
|
||||
soft limit and a 600-second hard limit. Do not override these task limits: recovery relies on the
|
||||
child having stopped before reclaiming its execution window. Beat checks for abandoned running
|
||||
jobs and publication claims every minute after the lifecycle gates are ready. Claims without
|
||||
@@ -260,89 +537,3 @@ changing client-supplied IP headers does not change the resolved address, and an
|
||||
untrusted pod cannot connect directly to the API. IP limits still need independent
|
||||
account/email limits because NAT can share public addresses and attackers can
|
||||
use multiple real addresses.
|
||||
|
||||
## How to Deploy Middleware for Developing Dify
|
||||
|
||||
1. **Middleware Setup**:
|
||||
- Use the `docker-compose.middleware.yaml` for setting up essential middleware services like databases and caches.
|
||||
- Navigate to the `docker` directory.
|
||||
- Ensure the `middleware.env` file is created by running `cp envs/middleware.env.example middleware.env` (refer to the `envs/middleware.env.example` file).
|
||||
2. **Running Middleware Services**:
|
||||
- Navigate to the `docker` directory.
|
||||
- Execute `docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d` to start PostgreSQL/MySQL (per `DB_TYPE`) plus the bundled Weaviate instance.
|
||||
|
||||
> Compose automatically loads `COMPOSE_PROFILES=${DB_TYPE:-postgresql},weaviate` from `middleware.env`, so no extra `--profile` flags are needed. Adjust variables in `middleware.env` if you want a different combination of services.
|
||||
|
||||
## Overview of `.env`, `.env.example`, and `envs/`
|
||||
|
||||
- `.env.example` contains only settings requiring manual configuration, such as the Compose service selection.
|
||||
- `.env` contains your deployment inputs and any explicit overrides.
|
||||
- `envs/*.env.example` files contain optional advanced configuration grouped by theme.
|
||||
|
||||
Keep the root `.env.example` limited to settings that require manual user configuration.
|
||||
Settings with usable application or Docker defaults must not appear there. Document optional,
|
||||
advanced, provider-specific, and service-specific overrides in the appropriate `envs/*.env.example` file.
|
||||
|
||||
Docker Compose loads Docker-specific defaults from `envs/core-services/shared.defaults`,
|
||||
then optional `envs/*.env` files, then `.env` so your overrides take precedence. Other defaults
|
||||
come from the application and each service in `docker-compose.yaml`; do not copy them into `.env`.
|
||||
The bundled credentials are intended for local deployment; override them for production using
|
||||
the matching security and service templates.
|
||||
|
||||
For the available variables and defaults, read the matching `envs/**/*.env.example` template and its service in `docker-compose.yaml`.
|
||||
|
||||
Custom worker queue lists set through `CELERY_QUEUES` or `CELERY_WORKER_QUEUES` must include
|
||||
`human_input_delivery` to process durable Human Input IM inbox events and recover
|
||||
unconfirmed Human Input v2 notifications, and
|
||||
`human_input_contact_sync` to process manual IM Contact directory synchronization.
|
||||
|
||||
Human Input IM channels in `WEBHOOK` mode build their Callback URL from `TRIGGER_URL`.
|
||||
Set it to the externally reachable HTTPS origin of the API when configuring a remote
|
||||
deployment. A localhost value is only suitable for local development. Reverse proxies
|
||||
must forward `/callbacks/human-input/v2/im/` to the API and preserve the request path,
|
||||
body, and provider signature headers. Copy the channel's Callback URL into the
|
||||
provider's interaction configuration after changing the public origin.
|
||||
|
||||
## Environment Variables Synchronization
|
||||
|
||||
When upgrading Dify or pulling the latest changes, new environment variables may be introduced in `.env.example` only when they require manual configuration,
|
||||
or in the optional files under `envs/` for advanced, provider-specific, and service-specific settings.
|
||||
|
||||
If you use the default workflow, review `.env.example` and supply any new deployment inputs that require manual configuration.
|
||||
|
||||
If you maintain a customized `.env` file copied from `.env.example`, an optional environment variables synchronization tool is provided.
|
||||
|
||||
> This tool performs a **one-way synchronization** from `.env.example` to `.env`.
|
||||
> Existing values in `.env` are never overwritten automatically.
|
||||
|
||||
### `dify-env-sync.sh` (Optional)
|
||||
|
||||
This script compares your current `.env` file with the latest `.env.example` template and helps safely apply new or updated environment variables.
|
||||
|
||||
**What it does**
|
||||
|
||||
- Creates a backup of the current `.env` file before making any changes
|
||||
- Synchronizes newly added environment variables from `.env.example`
|
||||
- Preserves the existing `.env`, including custom settings absent from `.env.example`
|
||||
- Displays differences and additional local overrides for review
|
||||
|
||||
**Backup behavior**
|
||||
|
||||
Before synchronization, the current `.env` file is saved to the `env-backup/` directory with a timestamped filename
|
||||
(e.g. `env-backup/.env.backup_20231218_143022`).
|
||||
|
||||
**When to use**
|
||||
|
||||
- After upgrading Dify to a newer version with a full `.env` file
|
||||
- When `.env.example` has been updated with new environment variables
|
||||
- When managing a large or heavily customized `.env` file copied from `.env.example`
|
||||
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
# Grant execution permission (first time only)
|
||||
chmod +x dify-env-sync.sh
|
||||
|
||||
# Run the synchronization
|
||||
./dify-env-sync.sh
|
||||
```
|
||||
+171
-307
@@ -1,11 +1,8 @@
|
||||
# Shared configuration using YAML anchors and env_file
|
||||
x-shared-api-worker-config: &shared-api-worker-config
|
||||
x-shared-api-config: &shared-api-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/api.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -60,7 +57,11 @@ x-shared-api-worker-config: &shared-api-worker-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/api.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/api.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -68,11 +69,8 @@ x-shared-api-worker-config: &shared-api-worker-config
|
||||
|
||||
x-shared-worker-config: &shared-worker-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -127,7 +125,11 @@ x-shared-worker-config: &shared-worker-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -143,11 +145,8 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
# Match the two-hour default task deadline plus shutdown margin for long document jobs.
|
||||
stop_grace_period: 125m
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -160,7 +159,11 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
required: false
|
||||
- path: ./envs/core-services/knowledge-fs-worker.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker.defaults
|
||||
environment: &knowledge-fs-celery-environment
|
||||
MODE: worker
|
||||
MIGRATION_ENABLED: "false"
|
||||
@@ -181,11 +184,8 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
|
||||
x-shared-worker-beat-config: &shared-worker-beat-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker-beat.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -240,7 +240,11 @@ x-shared-worker-beat-config: &shared-worker-beat-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker-beat.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker-beat.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -268,22 +272,10 @@ services:
|
||||
|
||||
# API service
|
||||
api:
|
||||
<<: *shared-api-worker-config
|
||||
<<: *shared-api-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
environment:
|
||||
MODE: api
|
||||
# The bundled Nginx supplies a verified client IP; keep direct API callers trusted.
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-true}
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
AGENT_BACKEND_BASE_URL: ${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
AGENT_BACKEND_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -318,17 +310,22 @@ services:
|
||||
|
||||
# WebSocket service for workflow collaboration.
|
||||
api_websocket:
|
||||
<<: *shared-api-worker-config
|
||||
<<: *shared-api-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
profiles:
|
||||
- collaboration
|
||||
environment:
|
||||
MODE: api
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-true}
|
||||
SERVER_WORKER_AMOUNT: ${API_WEBSOCKET_WORKER_AMOUNT:-1}
|
||||
SERVER_WORKER_CLASS: ${API_WEBSOCKET_WORKER_CLASS:-geventwebsocket.gunicorn.workers.GeventWebSocketWorker}
|
||||
SERVER_WORKER_CONNECTIONS: ${API_WEBSOCKET_WORKER_CONNECTIONS:-1000}
|
||||
GUNICORN_TIMEOUT: ${API_WEBSOCKET_GUNICORN_TIMEOUT:-360}
|
||||
# Resolve websocket settings after loading the shared/API service files.
|
||||
entrypoint:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
export SERVER_WORKER_AMOUNT="$${API_WEBSOCKET_WORKER_AMOUNT:-1}"
|
||||
export SERVER_WORKER_CLASS="$${API_WEBSOCKET_WORKER_CLASS:-geventwebsocket.gunicorn.workers.GeventWebSocketWorker}"
|
||||
export SERVER_WORKER_CONNECTIONS="$${API_WEBSOCKET_WORKER_CONNECTIONS:-1000}"
|
||||
export GUNICORN_TIMEOUT="$${API_WEBSOCKET_GUNICORN_TIMEOUT:-360}"
|
||||
exec /bin/bash /entrypoint.sh
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -347,20 +344,12 @@ services:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
|
||||
# worker service
|
||||
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||
worker:
|
||||
<<: *shared-worker-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
environment:
|
||||
MODE: worker
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
AGENT_BACKEND_BASE_URL: ${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
AGENT_BACKEND_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -407,9 +396,6 @@ services:
|
||||
CELERY_WORKER_POOL: prefork
|
||||
CELERY_WORKER_CONCURRENCY: ${KNOWLEDGE_FS_UPGRADE_WORKER_AMOUNT:-2}
|
||||
CELERY_PREFETCH_MULTIPLIER: 1
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -467,123 +453,91 @@ services:
|
||||
image: langgenius/dify-web:1.18.0
|
||||
restart: always
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/web.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||
SERVER_CONSOLE_API_URL: ${SERVER_CONSOLE_API_URL:-http://api:5001}
|
||||
APP_API_URL: ${APP_API_URL:-}
|
||||
AMPLITUDE_API_KEY: ${AMPLITUDE_API_KEY:-}
|
||||
TURNSTILE_SITE_KEY: ${TURNSTILE_SITE_KEY:-}
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN: ${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
NEXT_PUBLIC_SOCKET_URL: ${NEXT_PUBLIC_SOCKET_URL:-ws://localhost}
|
||||
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||
EXPERIMENTAL_ENABLE_VINEXT: ${EXPERIMENTAL_ENABLE_VINEXT:-false}
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-10}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
- ./envs/core-services/web.defaults
|
||||
|
||||
# The PostgreSQL database.
|
||||
db_postgres:
|
||||
env_file:
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
required: false
|
||||
- ./envs/databases/db-postgres.defaults
|
||||
image: postgres:15-alpine
|
||||
profiles:
|
||||
- postgresql
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
command: >
|
||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-200}'
|
||||
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
|
||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
||||
-c 'statement_timeout=${POSTGRES_STATEMENT_TIMEOUT:-0}'
|
||||
-c 'idle_in_transaction_session_timeout=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}'
|
||||
# Expand service-file settings inside the container, preserving the image's initialization.
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- >-
|
||||
exec docker-entrypoint.sh postgres
|
||||
-c "max_connections=$$POSTGRES_MAX_CONNECTIONS"
|
||||
-c "shared_buffers=$$POSTGRES_SHARED_BUFFERS"
|
||||
-c "work_mem=$$POSTGRES_WORK_MEM"
|
||||
-c "maintenance_work_mem=$$POSTGRES_MAINTENANCE_WORK_MEM"
|
||||
-c "effective_cache_size=$$POSTGRES_EFFECTIVE_CACHE_SIZE"
|
||||
-c "statement_timeout=$$POSTGRES_STATEMENT_TIMEOUT"
|
||||
-c "idle_in_transaction_session_timeout=$$POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT"
|
||||
volumes:
|
||||
- ./volumes/db/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"pg_isready",
|
||||
"-h",
|
||||
"db_postgres",
|
||||
"-U",
|
||||
"${DB_USERNAME:-postgres}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-dify}",
|
||||
]
|
||||
test: ["CMD-SHELL", 'pg_isready -h db_postgres -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"']
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 60
|
||||
|
||||
# The mysql database.
|
||||
db_mysql:
|
||||
env_file:
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-mysql.env
|
||||
required: false
|
||||
- ./envs/databases/db-mysql.defaults
|
||||
image: mysql:8.0
|
||||
profiles:
|
||||
- mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
MYSQL_DATABASE: ${DB_DATABASE:-dify}
|
||||
command: >
|
||||
--max_connections=${MYSQL_MAX_CONNECTIONS:-1000}
|
||||
--innodb_buffer_pool_size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
--innodb_log_file_size=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
--innodb_flush_log_at_trx_commit=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- >-
|
||||
exec docker-entrypoint.sh mysqld
|
||||
"--max_connections=$$MYSQL_MAX_CONNECTIONS"
|
||||
"--innodb_buffer_pool_size=$$MYSQL_INNODB_BUFFER_POOL_SIZE"
|
||||
"--innodb_log_file_size=$$MYSQL_INNODB_LOG_FILE_SIZE"
|
||||
"--innodb_flush_log_at_trx_commit=$$MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT"
|
||||
volumes:
|
||||
- ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}:/var/lib/mysql
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-u",
|
||||
"root",
|
||||
"-p${DB_PASSWORD:-difyai123456}",
|
||||
]
|
||||
test: ["CMD-SHELL", 'mysqladmin ping -u root -p"$$MYSQL_ROOT_PASSWORD"']
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
# The redis cache.
|
||||
redis:
|
||||
env_file:
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- ./envs/databases/redis.defaults
|
||||
image: redis:6-alpine
|
||||
restart: always
|
||||
environment:
|
||||
REDISCLI_AUTH: ${REDIS_PASSWORD:-difyai123456}
|
||||
volumes:
|
||||
# Mount the redis data directory to the container.
|
||||
- ./volumes/redis/data:/data
|
||||
# Set the redis password when startup redis server.
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||
command: ["sh", "-c", 'exec docker-entrypoint.sh redis-server --requirepass "$$REDIS_PASSWORD"']
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||
"redis-cli ping | grep -q PONG",
|
||||
]
|
||||
|
||||
# The DifySandbox
|
||||
@@ -596,23 +550,12 @@ services:
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
# The DifySandbox configurations
|
||||
# Make sure you are changing this key for your deployment with a strong key.
|
||||
# You can generate a strong key using `openssl rand -base64 42`.
|
||||
API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
||||
GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
||||
WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
||||
ENABLE_NETWORK: ${SANDBOX_ENABLE_NETWORK:-true}
|
||||
HTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}
|
||||
HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
|
||||
SANDBOX_PORT: ${SANDBOX_PORT:-8194}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
- ./envs/core-services/sandbox.defaults
|
||||
volumes:
|
||||
- ./volumes/sandbox/dependencies:/dependencies
|
||||
- ./volumes/sandbox/conf:/conf
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||
test: ["CMD-SHELL", 'curl -f "http://localhost:$$SANDBOX_PORT/health"']
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
|
||||
@@ -668,57 +611,13 @@ services:
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/plugin-daemon.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
environment:
|
||||
DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||
DB_SSL_MODE: ${DB_SSL_MODE:-disable}
|
||||
SERVER_PORT: ${PLUGIN_DAEMON_PORT:-5002}
|
||||
SERVER_KEY: ${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}
|
||||
MAX_PLUGIN_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PPROF_ENABLED: ${PLUGIN_PPROF_ENABLED:-false}
|
||||
DIFY_INNER_API_URL: ${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}
|
||||
DIFY_INNER_API_KEY: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd}
|
||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||
PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||
PLUGIN_INSTALLED_PATH: ${PLUGIN_INSTALLED_PATH:-plugin}
|
||||
PLUGIN_PACKAGE_CACHE_PATH: ${PLUGIN_PACKAGE_CACHE_PATH:-plugin_packages}
|
||||
PLUGIN_MEDIA_CACHE_PATH: ${PLUGIN_MEDIA_CACHE_PATH:-assets}
|
||||
PLUGIN_STORAGE_OSS_BUCKET: ${PLUGIN_STORAGE_OSS_BUCKET:-}
|
||||
S3_USE_AWS_MANAGED_IAM: ${PLUGIN_S3_USE_AWS_MANAGED_IAM:-false}
|
||||
S3_USE_AWS: ${PLUGIN_S3_USE_AWS:-false}
|
||||
S3_ENDPOINT: ${PLUGIN_S3_ENDPOINT:-}
|
||||
S3_USE_PATH_STYLE: ${PLUGIN_S3_USE_PATH_STYLE:-false}
|
||||
AWS_ACCESS_KEY: ${PLUGIN_AWS_ACCESS_KEY:-}
|
||||
AWS_SECRET_KEY: ${PLUGIN_AWS_SECRET_KEY:-}
|
||||
AWS_REGION: ${PLUGIN_AWS_REGION:-}
|
||||
AZURE_BLOB_STORAGE_CONNECTION_STRING: ${PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING:-}
|
||||
AZURE_BLOB_STORAGE_CONTAINER_NAME: ${PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME:-}
|
||||
TENCENT_COS_SECRET_KEY: ${PLUGIN_TENCENT_COS_SECRET_KEY:-}
|
||||
TENCENT_COS_SECRET_ID: ${PLUGIN_TENCENT_COS_SECRET_ID:-}
|
||||
TENCENT_COS_REGION: ${PLUGIN_TENCENT_COS_REGION:-}
|
||||
ALIYUN_OSS_REGION: ${PLUGIN_ALIYUN_OSS_REGION:-}
|
||||
ALIYUN_OSS_ENDPOINT: ${PLUGIN_ALIYUN_OSS_ENDPOINT:-}
|
||||
ALIYUN_OSS_ACCESS_KEY_ID: ${PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID:-}
|
||||
ALIYUN_OSS_ACCESS_KEY_SECRET: ${PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET:-}
|
||||
ALIYUN_OSS_AUTH_VERSION: ${PLUGIN_ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||
ALIYUN_OSS_PATH: ${PLUGIN_ALIYUN_OSS_PATH:-}
|
||||
VOLCENGINE_TOS_ENDPOINT: ${PLUGIN_VOLCENGINE_TOS_ENDPOINT:-}
|
||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||
SENTRY_ENABLED: ${PLUGIN_SENTRY_ENABLED:-false}
|
||||
SENTRY_DSN: ${PLUGIN_SENTRY_DSN:-}
|
||||
ports:
|
||||
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
||||
volumes:
|
||||
@@ -827,29 +726,14 @@ services:
|
||||
image: langgenius/dify-agent-backend:1.18.0
|
||||
restart: always
|
||||
env_file:
|
||||
- path: ./envs/core-services/dify-agent.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- path: ./envs/core-services/dify-agent.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
DIFY_AGENT_REDIS_URL: ${DIFY_AGENT_REDIS_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@redis:6379/2}
|
||||
DIFY_AGENT_PLUGIN_DAEMON_URL: ${DIFY_AGENT_PLUGIN_DAEMON_URL:-${PLUGIN_DAEMON_URL:-http://plugin_daemon:5002}}
|
||||
DIFY_AGENT_PLUGIN_DAEMON_API_KEY: ${DIFY_AGENT_PLUGIN_DAEMON_API_KEY:-${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}}
|
||||
DIFY_AGENT_INNER_API_URL: ${DIFY_AGENT_INNER_API_URL:-${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}}
|
||||
DIFY_AGENT_INNER_API_KEY: ${DIFY_AGENT_INNER_API_KEY:-${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}}
|
||||
DIFY_AGENT_RUNTIME_BACKEND: ${DIFY_AGENT_RUNTIME_BACKEND:-local}
|
||||
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT: ${DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT:-${DIFY_AGENT_SHELLCTL_ENTRYPOINT:-http://local_sandbox:5004}}
|
||||
DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN: ${DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN:-${DIFY_AGENT_SHELLCTL_AUTH_TOKEN:-}}
|
||||
DIFY_AGENT_STUB_API_BASE_URL: ${DIFY_AGENT_STUB_API_BASE_URL:-http://agent_backend:5050/agent-stub}
|
||||
DIFY_AGENT_SANDBOX_FILES_BASE_URL: ${DIFY_AGENT_SANDBOX_FILES_BASE_URL:-http://api:5001}
|
||||
# This is security-sensitive: it derives the JWE encryption key for Agent Stub bearer tokens.
|
||||
# Replace this development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
DIFY_AGENT_SERVER_SECRET_KEY: ${DIFY_AGENT_SERVER_SECRET_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY}
|
||||
DIFY_AGENT_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
- ./envs/core-services/dify-agent.defaults
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_started
|
||||
@@ -875,11 +759,10 @@ services:
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||
COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS: ${SSRF_PROXY_ALLOW_PRIVATE_IPS:-}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS: ${SSRF_PROXY_ALLOW_PRIVATE_DOMAINS:-}
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/ssrf-proxy.env
|
||||
required: false
|
||||
- ./envs/infrastructure/ssrf-proxy.defaults
|
||||
networks:
|
||||
# Needs to reach api and agent_backend as forward-proxy destinations.
|
||||
- default
|
||||
@@ -891,6 +774,10 @@ services:
|
||||
# for more information, please refer to
|
||||
# https://docs.dify.ai/en/self-host/deploy/troubleshooting/docker-issues#why-is-ssrf-proxy-needed
|
||||
ssrf_proxy:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/ssrf-proxy.env
|
||||
required: false
|
||||
- ./envs/infrastructure/ssrf-proxy.defaults
|
||||
image: ubuntu/squid:latest
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -903,12 +790,6 @@ services:
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
# pls clearly modify the squid env vars to fit your network environment.
|
||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||
COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS: ${SSRF_PROXY_ALLOW_PRIVATE_IPS:-}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS: ${SSRF_PROXY_ALLOW_PRIVATE_DOMAINS:-}
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -916,6 +797,10 @@ services:
|
||||
# Certbot service
|
||||
# use `docker-compose --profile certbot up` to start the certbot service.
|
||||
certbot:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/certbot.env
|
||||
required: false
|
||||
- ./envs/infrastructure/certbot.defaults
|
||||
image: certbot/certbot
|
||||
profiles:
|
||||
- certbot
|
||||
@@ -926,16 +811,16 @@ services:
|
||||
- ./volumes/certbot/conf/live:/etc/letsencrypt/live
|
||||
- ./certbot/update-cert.template.txt:/update-cert.template.txt
|
||||
- ./certbot/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
environment:
|
||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL:-}
|
||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-}
|
||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
command: ["tail", "-f", "/dev/null"]
|
||||
|
||||
# The nginx reverse proxy.
|
||||
# used for reverse proxying the API service and Web service.
|
||||
nginx:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/nginx.env
|
||||
required: false
|
||||
- ./envs/infrastructure/nginx.defaults
|
||||
image: nginx:latest
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -955,23 +840,8 @@ services:
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
|
||||
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
||||
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
||||
NGINX_PORT: ${NGINX_PORT:-80}
|
||||
# You're required to add your own SSL certificates/keys to the `./nginx/ssl` directory
|
||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||
NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false}
|
||||
NGINX_SOCKET_IO_UPSTREAM: ${NGINX_SOCKET_IO_UPSTREAM:-api_websocket:5001}
|
||||
CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-}
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
@@ -981,6 +851,10 @@ services:
|
||||
|
||||
# The Weaviate vector store.
|
||||
weaviate:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/weaviate.env
|
||||
required: false
|
||||
- ./envs/vectorstores/weaviate.defaults
|
||||
image: cr.weaviate.io/semitechnologies/weaviate:1.39.13
|
||||
profiles:
|
||||
- weaviate
|
||||
@@ -988,26 +862,12 @@ services:
|
||||
volumes:
|
||||
# Mount the Weaviate data directory to the con tainer.
|
||||
- ./volumes/weaviate:/var/lib/weaviate
|
||||
environment:
|
||||
# The Weaviate configurations
|
||||
# You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information.
|
||||
PERSISTENCE_DATA_PATH: ${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate}
|
||||
QUERY_DEFAULTS_LIMIT: ${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25}
|
||||
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: ${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false}
|
||||
DEFAULT_VECTORIZER_MODULE: ${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none}
|
||||
CLUSTER_HOSTNAME: ${WEAVIATE_CLUSTER_HOSTNAME:-node1}
|
||||
AUTHENTICATION_APIKEY_ENABLED: ${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true}
|
||||
AUTHENTICATION_APIKEY_ALLOWED_KEYS: ${WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/oceanbase.env
|
||||
required: false
|
||||
- ./envs/vectorstores/oceanbase.defaults
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
container_name: oceanbase
|
||||
profiles:
|
||||
@@ -1018,10 +878,6 @@ services:
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
LANG: C.UTF-8
|
||||
@@ -1032,7 +888,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p"$$OB_TENANT_PASSWORD" -e "SELECT 1;"',
|
||||
]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
@@ -1041,6 +897,10 @@ services:
|
||||
|
||||
# seekdb vector database
|
||||
seekdb:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/seekdb.env
|
||||
required: false
|
||||
- ./envs/vectorstores/seekdb.defaults
|
||||
image: oceanbase/seekdb:latest
|
||||
container_name: seekdb
|
||||
profiles:
|
||||
@@ -1049,8 +909,6 @@ services:
|
||||
volumes:
|
||||
- ./volumes/seekdb:/var/lib/oceanbase
|
||||
environment:
|
||||
ROOT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
MEMORY_LIMIT: ${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
REPORTER: dify-ai-seekdb
|
||||
ports:
|
||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
||||
@@ -1058,7 +916,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'mysql -h127.0.0.1 -P2881 -uroot -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
'mysql -h127.0.0.1 -P2881 -uroot -p"$$ROOT_PASSWORD" -e "SELECT 1;"',
|
||||
]
|
||||
interval: 5s
|
||||
retries: 60
|
||||
@@ -1067,26 +925,29 @@ services:
|
||||
# Qdrant vector store.
|
||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||
qdrant:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/qdrant.env
|
||||
required: false
|
||||
- ./envs/vectorstores/qdrant.defaults
|
||||
image: langgenius/qdrant:v1.8.3
|
||||
profiles:
|
||||
- qdrant
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/qdrant:/qdrant/storage
|
||||
environment:
|
||||
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
|
||||
|
||||
# The Couchbase vector store.
|
||||
couchbase-server:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/couchbase.env
|
||||
required: false
|
||||
- ./envs/vectorstores/couchbase.defaults
|
||||
build: ./couchbase-server
|
||||
profiles:
|
||||
- couchbase
|
||||
restart: always
|
||||
environment:
|
||||
- CLUSTER_NAME=dify_search
|
||||
- COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_USER:-Administrator}
|
||||
- COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_PASSWORD:-password}
|
||||
- COUCHBASE_BUCKET=${COUCHBASE_BUCKET_NAME:-Embeddings}
|
||||
- COUCHBASE_BUCKET_RAMSIZE=512
|
||||
- COUCHBASE_RAM_SIZE=2048
|
||||
- COUCHBASE_EVENTING_RAM_SIZE=512
|
||||
@@ -1106,7 +967,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"curl -s -f -u Administrator:password http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1",
|
||||
"curl -s -f -u \"$$COUCHBASE_ADMINISTRATOR_USERNAME:$$COUCHBASE_ADMINISTRATOR_PASSWORD\" http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1",
|
||||
]
|
||||
interval: 10s
|
||||
retries: 10
|
||||
@@ -1115,21 +976,14 @@ services:
|
||||
|
||||
# The pgvector vector database.
|
||||
pgvector:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/pgvector.env
|
||||
required: false
|
||||
- ./envs/vectorstores/pgvector.defaults
|
||||
image: pgvector/pgvector:pg16
|
||||
profiles:
|
||||
- pgvector
|
||||
restart: always
|
||||
environment:
|
||||
PGUSER: ${PGVECTOR_PGUSER:-postgres}
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD: ${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB: ${PGVECTOR_POSTGRES_DB:-dify}
|
||||
# postgres data directory
|
||||
PGDATA: ${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
# pg_bigm module for full text search
|
||||
PG_BIGM: ${PGVECTOR_PG_BIGM:-false}
|
||||
PG_BIGM_VERSION: ${PGVECTOR_PG_BIGM_VERSION:-1.2-20240606}
|
||||
volumes:
|
||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
@@ -1166,18 +1020,14 @@ services:
|
||||
|
||||
# pgvecto-rs vector store
|
||||
pgvecto-rs:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/pgvecto-rs.env
|
||||
required: false
|
||||
- ./envs/vectorstores/pgvecto-rs.defaults
|
||||
image: tensorchord/pgvecto-rs:pg16-v0.3.0
|
||||
profiles:
|
||||
- pgvecto-rs
|
||||
restart: always
|
||||
environment:
|
||||
PGUSER: ${PGVECTOR_PGUSER:-postgres}
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD: ${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB: ${PGVECTOR_POSTGRES_DB:-dify}
|
||||
# postgres data directory
|
||||
PGDATA: ${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
volumes:
|
||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
@@ -1188,19 +1038,23 @@ services:
|
||||
|
||||
# Chroma vector database
|
||||
chroma:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/chroma.env
|
||||
required: false
|
||||
- ./envs/vectorstores/chroma.defaults
|
||||
image: ghcr.io/chroma-core/chroma:0.5.20
|
||||
profiles:
|
||||
- chroma
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/chroma:/chroma/chroma
|
||||
environment:
|
||||
CHROMA_SERVER_AUTHN_CREDENTIALS: ${CHROMA_SERVER_AUTHN_CREDENTIALS:-difyai123456}
|
||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
|
||||
# InterSystems IRIS vector database
|
||||
iris:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/iris.env
|
||||
required: false
|
||||
- ./envs/vectorstores/iris.defaults
|
||||
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||
profiles:
|
||||
- iris
|
||||
@@ -1217,11 +1071,14 @@ services:
|
||||
entrypoint: ["/custom-entrypoint.sh"]
|
||||
tty: true
|
||||
environment:
|
||||
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||
ISC_DATA_DIRECTORY: /durable/iris
|
||||
|
||||
# Oracle vector database
|
||||
oracle:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/oracle.env
|
||||
required: false
|
||||
- ./envs/vectorstores/oracle.defaults
|
||||
image: container-registry.oracle.com/database/free:latest
|
||||
profiles:
|
||||
- oracle
|
||||
@@ -1231,21 +1088,19 @@ services:
|
||||
type: volume
|
||||
target: /opt/oracle/oradata
|
||||
- ./startupscripts:/opt/oracle/scripts/startup
|
||||
environment:
|
||||
ORACLE_PWD: ${ORACLE_PWD:-Dify123456}
|
||||
ORACLE_CHARACTERSET: ${ORACLE_CHARACTERSET:-AL32UTF8}
|
||||
|
||||
# Milvus vector database services
|
||||
etcd:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/etcd.env
|
||||
required: false
|
||||
- ./envs/infrastructure/etcd.defaults
|
||||
container_name: milvus-etcd
|
||||
image: quay.io/coreos/etcd:v3.5.5
|
||||
profiles:
|
||||
- milvus
|
||||
environment:
|
||||
ETCD_AUTO_COMPACTION_MODE: ${ETCD_AUTO_COMPACTION_MODE:-revision}
|
||||
ETCD_AUTO_COMPACTION_RETENTION: ${ETCD_AUTO_COMPACTION_RETENTION:-1000}
|
||||
ETCD_QUOTA_BACKEND_BYTES: ${ETCD_QUOTA_BACKEND_BYTES:-4294967296}
|
||||
ETCD_SNAPSHOT_COUNT: ${ETCD_SNAPSHOT_COUNT:-50000}
|
||||
volumes:
|
||||
- ./volumes/milvus/etcd:/etcd
|
||||
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
|
||||
@@ -1258,13 +1113,16 @@ services:
|
||||
- milvus
|
||||
|
||||
minio:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/minio.env
|
||||
required: false
|
||||
- ./envs/infrastructure/minio.defaults
|
||||
container_name: milvus-minio
|
||||
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
|
||||
profiles:
|
||||
- milvus
|
||||
environment:
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
|
||||
volumes:
|
||||
- ./volumes/milvus/minio:/minio_data
|
||||
command: minio server /minio_data --console-address ":9001"
|
||||
@@ -1277,15 +1135,17 @@ services:
|
||||
- milvus
|
||||
|
||||
milvus-standalone:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- ./envs/infrastructure/milvus-standalone.defaults
|
||||
container_name: milvus-standalone
|
||||
image: milvusdb/milvus:v2.6.3
|
||||
profiles:
|
||||
- milvus
|
||||
command: ["milvus", "run", "standalone"]
|
||||
environment:
|
||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||
common.security.authorizationEnabled: ${MILVUS_AUTHORIZATION_ENABLED:-true}
|
||||
volumes:
|
||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||
healthcheck:
|
||||
@@ -1305,15 +1165,14 @@ services:
|
||||
|
||||
# Opensearch vector database
|
||||
opensearch:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/opensearch.env
|
||||
required: false
|
||||
- ./envs/vectorstores/opensearch.defaults
|
||||
container_name: opensearch
|
||||
image: opensearchproject/opensearch:latest
|
||||
profiles:
|
||||
- opensearch
|
||||
environment:
|
||||
discovery.type: ${OPENSEARCH_DISCOVERY_TYPE:-single-node}
|
||||
bootstrap.memory_lock: ${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true}
|
||||
OPENSEARCH_JAVA_OPTS: -Xms${OPENSEARCH_JAVA_OPTS_MIN:-512m} -Xmx${OPENSEARCH_JAVA_OPTS_MAX:-1024m}
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD: ${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-Qazwsxedc!@#123}
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: ${OPENSEARCH_MEMLOCK_SOFT:--1}
|
||||
@@ -1342,16 +1201,17 @@ services:
|
||||
|
||||
# opengauss vector database.
|
||||
opengauss:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/opengauss.env
|
||||
required: false
|
||||
- ./envs/vectorstores/opengauss.defaults
|
||||
image: opengauss/opengauss:7.0.0-RC1
|
||||
profiles:
|
||||
- opengauss
|
||||
privileged: true
|
||||
restart: always
|
||||
environment:
|
||||
GS_USERNAME: ${OPENGAUSS_USER:-postgres}
|
||||
GS_PASSWORD: ${OPENGAUSS_PASSWORD:-Dify@123}
|
||||
GS_PORT: ${OPENGAUSS_PORT:-6600}
|
||||
GS_DB: ${OPENGAUSS_DATABASE:-dify}
|
||||
volumes:
|
||||
- ./volumes/opengauss/data:/var/lib/opengauss/data
|
||||
healthcheck:
|
||||
@@ -1392,18 +1252,17 @@ services:
|
||||
# https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html
|
||||
# https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-prod-prerequisites
|
||||
elasticsearch:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/elasticsearch.env
|
||||
required: false
|
||||
- ./envs/vectorstores/elasticsearch.defaults
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:8.14.3
|
||||
container_name: elasticsearch
|
||||
profiles:
|
||||
- elasticsearch
|
||||
- elasticsearch-ja
|
||||
restart: always
|
||||
volumes:
|
||||
- ./elasticsearch/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
- dify_es01_data:/usr/share/elasticsearch/data
|
||||
environment:
|
||||
ELASTIC_PASSWORD: ${ELASTICSEARCH_PASSWORD:-elastic}
|
||||
VECTOR_STORE: ${VECTOR_STORE:-}
|
||||
cluster.name: dify-es-cluster
|
||||
node.name: dify-es0
|
||||
discovery.type: single-node
|
||||
@@ -1411,6 +1270,11 @@ services:
|
||||
xpack.security.enabled: "true"
|
||||
xpack.security.enrollment.enabled: "false"
|
||||
xpack.security.http.ssl.enabled: "false"
|
||||
# Backend selection also controls the Japanese analyzer installed by the entrypoint.
|
||||
VECTOR_STORE: ${VECTOR_STORE:-}
|
||||
volumes:
|
||||
- ./elasticsearch/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
- dify_es01_data:/usr/share/elasticsearch/data
|
||||
ports:
|
||||
- ${ELASTICSEARCH_PORT:-9200}:9200
|
||||
deploy:
|
||||
|
||||
@@ -26,8 +26,6 @@ services:
|
||||
dockerfile: dify-agent/Dockerfile
|
||||
environment:
|
||||
DIFY_AGENT_RUNTIME_BACKEND: e2b
|
||||
DIFY_AGENT_E2B_API_KEY: ${DIFY_AGENT_E2B_API_KEY:-${E2B_API_KEY:-${E2B_API_TOKEN:-}}}
|
||||
DIFY_AGENT_E2B_TEMPLATE: ${DIFY_AGENT_E2B_TEMPLATE:-difys-default-team/dify-agent-local-sandbox}
|
||||
ports:
|
||||
- "${EXPOSE_AGENT_BACKEND_PORT:-15050}:5050"
|
||||
|
||||
|
||||
+171
-307
@@ -5,13 +5,10 @@
|
||||
# ==================================================================
|
||||
|
||||
# Shared configuration using YAML anchors and env_file
|
||||
x-shared-api-worker-config: &shared-api-worker-config
|
||||
x-shared-api-config: &shared-api-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/api.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -66,7 +63,11 @@ x-shared-api-worker-config: &shared-api-worker-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/api.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/api.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -74,11 +75,8 @@ x-shared-api-worker-config: &shared-api-worker-config
|
||||
|
||||
x-shared-worker-config: &shared-worker-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -133,7 +131,11 @@ x-shared-worker-config: &shared-worker-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -149,11 +151,8 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
# Match the two-hour default task deadline plus shutdown margin for long document jobs.
|
||||
stop_grace_period: 125m
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -166,7 +165,11 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
required: false
|
||||
- path: ./envs/core-services/knowledge-fs-worker.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker.defaults
|
||||
environment: &knowledge-fs-celery-environment
|
||||
MODE: worker
|
||||
MIGRATION_ENABLED: "false"
|
||||
@@ -187,11 +190,8 @@ x-knowledge-fs-celery-worker: &knowledge-fs-celery-worker
|
||||
|
||||
x-shared-worker-beat-config: &shared-worker-beat-config
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/shared.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker-beat.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
@@ -246,7 +246,11 @@ x-shared-worker-beat-config: &shared-worker-beat-config
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- path: ./envs/core-services/worker-beat.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/worker-beat.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -274,22 +278,10 @@ services:
|
||||
|
||||
# API service
|
||||
api:
|
||||
<<: *shared-api-worker-config
|
||||
<<: *shared-api-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
environment:
|
||||
MODE: api
|
||||
# The bundled Nginx supplies a verified client IP; keep direct API callers trusted.
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-true}
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
PLUGIN_REMOTE_INSTALL_HOST: ${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||
PLUGIN_REMOTE_INSTALL_PORT: ${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_DAEMON_TIMEOUT: ${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
AGENT_BACKEND_BASE_URL: ${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
AGENT_BACKEND_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -324,17 +316,22 @@ services:
|
||||
|
||||
# WebSocket service for workflow collaboration.
|
||||
api_websocket:
|
||||
<<: *shared-api-worker-config
|
||||
<<: *shared-api-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
profiles:
|
||||
- collaboration
|
||||
environment:
|
||||
MODE: api
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED: ${RESPECT_XFORWARD_HEADERS_ENABLED:-true}
|
||||
SERVER_WORKER_AMOUNT: ${API_WEBSOCKET_WORKER_AMOUNT:-1}
|
||||
SERVER_WORKER_CLASS: ${API_WEBSOCKET_WORKER_CLASS:-geventwebsocket.gunicorn.workers.GeventWebSocketWorker}
|
||||
SERVER_WORKER_CONNECTIONS: ${API_WEBSOCKET_WORKER_CONNECTIONS:-1000}
|
||||
GUNICORN_TIMEOUT: ${API_WEBSOCKET_GUNICORN_TIMEOUT:-360}
|
||||
# Resolve websocket settings after loading the shared/API service files.
|
||||
entrypoint:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
export SERVER_WORKER_AMOUNT="$${API_WEBSOCKET_WORKER_AMOUNT:-1}"
|
||||
export SERVER_WORKER_CLASS="$${API_WEBSOCKET_WORKER_CLASS:-geventwebsocket.gunicorn.workers.GeventWebSocketWorker}"
|
||||
export SERVER_WORKER_CONNECTIONS="$${API_WEBSOCKET_WORKER_CONNECTIONS:-1000}"
|
||||
export GUNICORN_TIMEOUT="$${API_WEBSOCKET_GUNICORN_TIMEOUT:-360}"
|
||||
exec /bin/bash /entrypoint.sh
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -353,20 +350,12 @@ services:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
|
||||
# worker service
|
||||
# The Celery worker for processing all queues (dataset, workflow, mail, etc.)
|
||||
worker:
|
||||
<<: *shared-worker-config
|
||||
image: langgenius/dify-api:1.18.0
|
||||
environment:
|
||||
MODE: worker
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
AGENT_BACKEND_BASE_URL: ${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
AGENT_BACKEND_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -413,9 +402,6 @@ services:
|
||||
CELERY_WORKER_POOL: prefork
|
||||
CELERY_WORKER_CONCURRENCY: ${KNOWLEDGE_FS_UPGRADE_WORKER_AMOUNT:-2}
|
||||
CELERY_PREFETCH_MULTIPLIER: 1
|
||||
SENTRY_DSN: ${API_SENTRY_DSN:-}
|
||||
SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
depends_on:
|
||||
init_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -473,123 +459,91 @@ services:
|
||||
image: langgenius/dify-web:1.18.0
|
||||
restart: always
|
||||
env_file:
|
||||
- ./envs/core-services/shared.defaults
|
||||
- path: ./envs/core-services/web.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
CONSOLE_API_URL: ${CONSOLE_API_URL:-}
|
||||
SERVER_CONSOLE_API_URL: ${SERVER_CONSOLE_API_URL:-http://api:5001}
|
||||
APP_API_URL: ${APP_API_URL:-}
|
||||
AMPLITUDE_API_KEY: ${AMPLITUDE_API_KEY:-}
|
||||
TURNSTILE_SITE_KEY: ${TURNSTILE_SITE_KEY:-}
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN: ${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
NEXT_PUBLIC_SOCKET_URL: ${NEXT_PUBLIC_SOCKET_URL:-ws://localhost}
|
||||
SENTRY_DSN: ${WEB_SENTRY_DSN:-}
|
||||
NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
|
||||
EXPERIMENTAL_ENABLE_VINEXT: ${EXPERIMENTAL_ENABLE_VINEXT:-false}
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-10}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
||||
LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
|
||||
MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
|
||||
MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
|
||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||
ENABLE_WEBSITE_JINAREADER: ${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL: ${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL: ${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
- ./envs/core-services/web.defaults
|
||||
|
||||
# The PostgreSQL database.
|
||||
db_postgres:
|
||||
env_file:
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
required: false
|
||||
- ./envs/databases/db-postgres.defaults
|
||||
image: postgres:15-alpine
|
||||
profiles:
|
||||
- postgresql
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${DB_USERNAME:-postgres}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_DB: ${DB_DATABASE:-dify}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
command: >
|
||||
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-200}'
|
||||
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
|
||||
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
|
||||
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
|
||||
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
|
||||
-c 'statement_timeout=${POSTGRES_STATEMENT_TIMEOUT:-0}'
|
||||
-c 'idle_in_transaction_session_timeout=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}'
|
||||
# Expand service-file settings inside the container, preserving the image's initialization.
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- >-
|
||||
exec docker-entrypoint.sh postgres
|
||||
-c "max_connections=$$POSTGRES_MAX_CONNECTIONS"
|
||||
-c "shared_buffers=$$POSTGRES_SHARED_BUFFERS"
|
||||
-c "work_mem=$$POSTGRES_WORK_MEM"
|
||||
-c "maintenance_work_mem=$$POSTGRES_MAINTENANCE_WORK_MEM"
|
||||
-c "effective_cache_size=$$POSTGRES_EFFECTIVE_CACHE_SIZE"
|
||||
-c "statement_timeout=$$POSTGRES_STATEMENT_TIMEOUT"
|
||||
-c "idle_in_transaction_session_timeout=$$POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT"
|
||||
volumes:
|
||||
- ./volumes/db/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"pg_isready",
|
||||
"-h",
|
||||
"db_postgres",
|
||||
"-U",
|
||||
"${DB_USERNAME:-postgres}",
|
||||
"-d",
|
||||
"${DB_DATABASE:-dify}",
|
||||
]
|
||||
test: ["CMD-SHELL", 'pg_isready -h db_postgres -U "$$POSTGRES_USER" -d "$$POSTGRES_DB"']
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 60
|
||||
|
||||
# The mysql database.
|
||||
db_mysql:
|
||||
env_file:
|
||||
- path: ./envs/databases/db-postgres.env
|
||||
required: false
|
||||
- path: ./envs/databases/db-mysql.env
|
||||
required: false
|
||||
- ./envs/databases/db-mysql.defaults
|
||||
image: mysql:8.0
|
||||
profiles:
|
||||
- mysql
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-difyai123456}
|
||||
MYSQL_DATABASE: ${DB_DATABASE:-dify}
|
||||
command: >
|
||||
--max_connections=${MYSQL_MAX_CONNECTIONS:-1000}
|
||||
--innodb_buffer_pool_size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
--innodb_log_file_size=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
--innodb_flush_log_at_trx_commit=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- >-
|
||||
exec docker-entrypoint.sh mysqld
|
||||
"--max_connections=$$MYSQL_MAX_CONNECTIONS"
|
||||
"--innodb_buffer_pool_size=$$MYSQL_INNODB_BUFFER_POOL_SIZE"
|
||||
"--innodb_log_file_size=$$MYSQL_INNODB_LOG_FILE_SIZE"
|
||||
"--innodb_flush_log_at_trx_commit=$$MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT"
|
||||
volumes:
|
||||
- ${MYSQL_HOST_VOLUME:-./volumes/mysql/data}:/var/lib/mysql
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"mysqladmin",
|
||||
"ping",
|
||||
"-u",
|
||||
"root",
|
||||
"-p${DB_PASSWORD:-difyai123456}",
|
||||
]
|
||||
test: ["CMD-SHELL", 'mysqladmin ping -u root -p"$$MYSQL_ROOT_PASSWORD"']
|
||||
interval: 1s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
# The redis cache.
|
||||
redis:
|
||||
env_file:
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- ./envs/databases/redis.defaults
|
||||
image: redis:6-alpine
|
||||
restart: always
|
||||
environment:
|
||||
REDISCLI_AUTH: ${REDIS_PASSWORD:-difyai123456}
|
||||
volumes:
|
||||
# Mount the redis data directory to the container.
|
||||
- ./volumes/redis/data:/data
|
||||
# Set the redis password when startup redis server.
|
||||
command: redis-server --requirepass ${REDIS_PASSWORD:-difyai123456}
|
||||
command: ["sh", "-c", 'exec docker-entrypoint.sh redis-server --requirepass "$$REDIS_PASSWORD"']
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"redis-cli -a ${REDIS_PASSWORD:-difyai123456} ping | grep -q PONG",
|
||||
"redis-cli ping | grep -q PONG",
|
||||
]
|
||||
|
||||
# The DifySandbox
|
||||
@@ -602,23 +556,12 @@ services:
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
# The DifySandbox configurations
|
||||
# Make sure you are changing this key for your deployment with a strong key.
|
||||
# You can generate a strong key using `openssl rand -base64 42`.
|
||||
API_KEY: ${SANDBOX_API_KEY:-dify-sandbox}
|
||||
GIN_MODE: ${SANDBOX_GIN_MODE:-release}
|
||||
WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15}
|
||||
ENABLE_NETWORK: ${SANDBOX_ENABLE_NETWORK:-true}
|
||||
HTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}
|
||||
HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
|
||||
SANDBOX_PORT: ${SANDBOX_PORT:-8194}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
- ./envs/core-services/sandbox.defaults
|
||||
volumes:
|
||||
- ./volumes/sandbox/dependencies:/dependencies
|
||||
- ./volumes/sandbox/conf:/conf
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8194/health"]
|
||||
test: ["CMD-SHELL", 'curl -f "http://localhost:$$SANDBOX_PORT/health"']
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
|
||||
@@ -674,57 +617,13 @@ services:
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- ./.env
|
||||
- ./envs/core-services/shared.defaults
|
||||
- ./envs/core-services/plugin-daemon.defaults
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
environment:
|
||||
DB_DATABASE: ${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||
DB_SSL_MODE: ${DB_SSL_MODE:-disable}
|
||||
SERVER_PORT: ${PLUGIN_DAEMON_PORT:-5002}
|
||||
SERVER_KEY: ${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}
|
||||
MAX_PLUGIN_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PPROF_ENABLED: ${PLUGIN_PPROF_ENABLED:-false}
|
||||
DIFY_INNER_API_URL: ${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}
|
||||
DIFY_INNER_API_KEY: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_DEBUGGING_PORT:-5003}
|
||||
PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd}
|
||||
FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true}
|
||||
PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||
PLUGIN_STDIO_BUFFER_SIZE: ${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE: ${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||
PIP_MIRROR_URL: ${PIP_MIRROR_URL:-}
|
||||
PLUGIN_STORAGE_TYPE: ${PLUGIN_STORAGE_TYPE:-local}
|
||||
PLUGIN_STORAGE_LOCAL_ROOT: ${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||
PLUGIN_INSTALLED_PATH: ${PLUGIN_INSTALLED_PATH:-plugin}
|
||||
PLUGIN_PACKAGE_CACHE_PATH: ${PLUGIN_PACKAGE_CACHE_PATH:-plugin_packages}
|
||||
PLUGIN_MEDIA_CACHE_PATH: ${PLUGIN_MEDIA_CACHE_PATH:-assets}
|
||||
PLUGIN_STORAGE_OSS_BUCKET: ${PLUGIN_STORAGE_OSS_BUCKET:-}
|
||||
S3_USE_AWS_MANAGED_IAM: ${PLUGIN_S3_USE_AWS_MANAGED_IAM:-false}
|
||||
S3_USE_AWS: ${PLUGIN_S3_USE_AWS:-false}
|
||||
S3_ENDPOINT: ${PLUGIN_S3_ENDPOINT:-}
|
||||
S3_USE_PATH_STYLE: ${PLUGIN_S3_USE_PATH_STYLE:-false}
|
||||
AWS_ACCESS_KEY: ${PLUGIN_AWS_ACCESS_KEY:-}
|
||||
AWS_SECRET_KEY: ${PLUGIN_AWS_SECRET_KEY:-}
|
||||
AWS_REGION: ${PLUGIN_AWS_REGION:-}
|
||||
AZURE_BLOB_STORAGE_CONNECTION_STRING: ${PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING:-}
|
||||
AZURE_BLOB_STORAGE_CONTAINER_NAME: ${PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME:-}
|
||||
TENCENT_COS_SECRET_KEY: ${PLUGIN_TENCENT_COS_SECRET_KEY:-}
|
||||
TENCENT_COS_SECRET_ID: ${PLUGIN_TENCENT_COS_SECRET_ID:-}
|
||||
TENCENT_COS_REGION: ${PLUGIN_TENCENT_COS_REGION:-}
|
||||
ALIYUN_OSS_REGION: ${PLUGIN_ALIYUN_OSS_REGION:-}
|
||||
ALIYUN_OSS_ENDPOINT: ${PLUGIN_ALIYUN_OSS_ENDPOINT:-}
|
||||
ALIYUN_OSS_ACCESS_KEY_ID: ${PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID:-}
|
||||
ALIYUN_OSS_ACCESS_KEY_SECRET: ${PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET:-}
|
||||
ALIYUN_OSS_AUTH_VERSION: ${PLUGIN_ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||
ALIYUN_OSS_PATH: ${PLUGIN_ALIYUN_OSS_PATH:-}
|
||||
VOLCENGINE_TOS_ENDPOINT: ${PLUGIN_VOLCENGINE_TOS_ENDPOINT:-}
|
||||
VOLCENGINE_TOS_ACCESS_KEY: ${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||
VOLCENGINE_TOS_SECRET_KEY: ${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||
VOLCENGINE_TOS_REGION: ${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||
SENTRY_ENABLED: ${PLUGIN_SENTRY_ENABLED:-false}
|
||||
SENTRY_DSN: ${PLUGIN_SENTRY_DSN:-}
|
||||
ports:
|
||||
- "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}"
|
||||
volumes:
|
||||
@@ -833,29 +732,14 @@ services:
|
||||
image: langgenius/dify-agent-backend:1.18.0
|
||||
restart: always
|
||||
env_file:
|
||||
- path: ./envs/core-services/dify-agent.env
|
||||
required: false
|
||||
- path: ./envs/security.env
|
||||
required: false
|
||||
- path: ./envs/databases/redis.env
|
||||
required: false
|
||||
- path: ./envs/core-services/dify-agent.env
|
||||
required: false
|
||||
- ./.env
|
||||
environment:
|
||||
DIFY_AGENT_REDIS_URL: ${DIFY_AGENT_REDIS_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@redis:6379/2}
|
||||
DIFY_AGENT_PLUGIN_DAEMON_URL: ${DIFY_AGENT_PLUGIN_DAEMON_URL:-${PLUGIN_DAEMON_URL:-http://plugin_daemon:5002}}
|
||||
DIFY_AGENT_PLUGIN_DAEMON_API_KEY: ${DIFY_AGENT_PLUGIN_DAEMON_API_KEY:-${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}}
|
||||
DIFY_AGENT_INNER_API_URL: ${DIFY_AGENT_INNER_API_URL:-${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}}
|
||||
DIFY_AGENT_INNER_API_KEY: ${DIFY_AGENT_INNER_API_KEY:-${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}}
|
||||
DIFY_AGENT_RUNTIME_BACKEND: ${DIFY_AGENT_RUNTIME_BACKEND:-local}
|
||||
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT: ${DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT:-${DIFY_AGENT_SHELLCTL_ENTRYPOINT:-http://local_sandbox:5004}}
|
||||
DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN: ${DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN:-${DIFY_AGENT_SHELLCTL_AUTH_TOKEN:-}}
|
||||
DIFY_AGENT_STUB_API_BASE_URL: ${DIFY_AGENT_STUB_API_BASE_URL:-http://agent_backend:5050/agent-stub}
|
||||
DIFY_AGENT_SANDBOX_FILES_BASE_URL: ${DIFY_AGENT_SANDBOX_FILES_BASE_URL:-http://api:5001}
|
||||
# This is security-sensitive: it derives the JWE encryption key for Agent Stub bearer tokens.
|
||||
# Replace this development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
DIFY_AGENT_SERVER_SECRET_KEY: ${DIFY_AGENT_SERVER_SECRET_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY}
|
||||
DIFY_AGENT_API_TOKEN: ${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
- ./envs/core-services/dify-agent.defaults
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_started
|
||||
@@ -881,11 +765,10 @@ services:
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||
COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS: ${SSRF_PROXY_ALLOW_PRIVATE_IPS:-}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS: ${SSRF_PROXY_ALLOW_PRIVATE_DOMAINS:-}
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/ssrf-proxy.env
|
||||
required: false
|
||||
- ./envs/infrastructure/ssrf-proxy.defaults
|
||||
networks:
|
||||
# Needs to reach api and agent_backend as forward-proxy destinations.
|
||||
- default
|
||||
@@ -897,6 +780,10 @@ services:
|
||||
# for more information, please refer to
|
||||
# https://docs.dify.ai/en/self-host/deploy/troubleshooting/docker-issues#why-is-ssrf-proxy-needed
|
||||
ssrf_proxy:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/ssrf-proxy.env
|
||||
required: false
|
||||
- ./envs/infrastructure/ssrf-proxy.defaults
|
||||
image: ubuntu/squid:latest
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -909,12 +796,6 @@ services:
|
||||
"-c",
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
# pls clearly modify the squid env vars to fit your network environment.
|
||||
HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
|
||||
COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS: ${SSRF_PROXY_ALLOW_PRIVATE_IPS:-}
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS: ${SSRF_PROXY_ALLOW_PRIVATE_DOMAINS:-}
|
||||
networks:
|
||||
- ssrf_proxy_network
|
||||
- default
|
||||
@@ -922,6 +803,10 @@ services:
|
||||
# Certbot service
|
||||
# use `docker-compose --profile certbot up` to start the certbot service.
|
||||
certbot:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/certbot.env
|
||||
required: false
|
||||
- ./envs/infrastructure/certbot.defaults
|
||||
image: certbot/certbot
|
||||
profiles:
|
||||
- certbot
|
||||
@@ -932,16 +817,16 @@ services:
|
||||
- ./volumes/certbot/conf/live:/etc/letsencrypt/live
|
||||
- ./certbot/update-cert.template.txt:/update-cert.template.txt
|
||||
- ./certbot/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
environment:
|
||||
- CERTBOT_EMAIL=${CERTBOT_EMAIL:-}
|
||||
- CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-}
|
||||
- CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
command: ["tail", "-f", "/dev/null"]
|
||||
|
||||
# The nginx reverse proxy.
|
||||
# used for reverse proxying the API service and Web service.
|
||||
nginx:
|
||||
env_file:
|
||||
- path: ./envs/infrastructure/nginx.env
|
||||
required: false
|
||||
- ./envs/infrastructure/nginx.defaults
|
||||
image: nginx:latest
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -961,23 +846,8 @@ services:
|
||||
"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh",
|
||||
]
|
||||
environment:
|
||||
NGINX_SERVER_NAME: ${NGINX_SERVER_NAME:-_}
|
||||
NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false}
|
||||
NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443}
|
||||
NGINX_PORT: ${NGINX_PORT:-80}
|
||||
# You're required to add your own SSL certificates/keys to the `./nginx/ssl` directory
|
||||
# and modify the env vars below in .env if HTTPS_ENABLED is true.
|
||||
NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||
NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||
NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false}
|
||||
NGINX_SOCKET_IO_UPSTREAM: ${NGINX_SOCKET_IO_UPSTREAM:-api_websocket:5001}
|
||||
CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-}
|
||||
depends_on:
|
||||
- api
|
||||
- web
|
||||
@@ -987,6 +857,10 @@ services:
|
||||
|
||||
# The Weaviate vector store.
|
||||
weaviate:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/weaviate.env
|
||||
required: false
|
||||
- ./envs/vectorstores/weaviate.defaults
|
||||
image: cr.weaviate.io/semitechnologies/weaviate:1.39.13
|
||||
profiles:
|
||||
- weaviate
|
||||
@@ -994,26 +868,12 @@ services:
|
||||
volumes:
|
||||
# Mount the Weaviate data directory to the con tainer.
|
||||
- ./volumes/weaviate:/var/lib/weaviate
|
||||
environment:
|
||||
# The Weaviate configurations
|
||||
# You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information.
|
||||
PERSISTENCE_DATA_PATH: ${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate}
|
||||
QUERY_DEFAULTS_LIMIT: ${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25}
|
||||
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: ${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false}
|
||||
DEFAULT_VECTORIZER_MODULE: ${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none}
|
||||
CLUSTER_HOSTNAME: ${WEAVIATE_CLUSTER_HOSTNAME:-node1}
|
||||
AUTHENTICATION_APIKEY_ENABLED: ${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true}
|
||||
AUTHENTICATION_APIKEY_ALLOWED_KEYS: ${WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
AUTHENTICATION_APIKEY_USERS: ${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
DISABLE_TELEMETRY: ${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ENABLE_TOKENIZER_GSE: ${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_JA: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_KR: ${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
|
||||
# OceanBase vector database
|
||||
oceanbase:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/oceanbase.env
|
||||
required: false
|
||||
- ./envs/vectorstores/oceanbase.defaults
|
||||
image: oceanbase/oceanbase-ce:4.3.5-lts
|
||||
container_name: oceanbase
|
||||
profiles:
|
||||
@@ -1024,10 +884,6 @@ services:
|
||||
- ./volumes/oceanbase/conf:/root/.obd/cluster
|
||||
- ./volumes/oceanbase/init.d:/root/boot/init.d
|
||||
environment:
|
||||
OB_MEMORY_LIMIT: ${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_CLUSTER_NAME: ${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_SERVER_IP: 127.0.0.1
|
||||
MODE: mini
|
||||
LANG: C.UTF-8
|
||||
@@ -1038,7 +894,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
'obclient -h127.0.0.1 -P2881 -uroot@test -p"$$OB_TENANT_PASSWORD" -e "SELECT 1;"',
|
||||
]
|
||||
interval: 10s
|
||||
retries: 30
|
||||
@@ -1047,6 +903,10 @@ services:
|
||||
|
||||
# seekdb vector database
|
||||
seekdb:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/seekdb.env
|
||||
required: false
|
||||
- ./envs/vectorstores/seekdb.defaults
|
||||
image: oceanbase/seekdb:latest
|
||||
container_name: seekdb
|
||||
profiles:
|
||||
@@ -1055,8 +915,6 @@ services:
|
||||
volumes:
|
||||
- ./volumes/seekdb:/var/lib/oceanbase
|
||||
environment:
|
||||
ROOT_PASSWORD: ${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
MEMORY_LIMIT: ${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
REPORTER: dify-ai-seekdb
|
||||
ports:
|
||||
- "${OCEANBASE_VECTOR_PORT:-2881}:2881"
|
||||
@@ -1064,7 +922,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
'mysql -h127.0.0.1 -P2881 -uroot -p${OCEANBASE_VECTOR_PASSWORD:-difyai123456} -e "SELECT 1;"',
|
||||
'mysql -h127.0.0.1 -P2881 -uroot -p"$$ROOT_PASSWORD" -e "SELECT 1;"',
|
||||
]
|
||||
interval: 5s
|
||||
retries: 60
|
||||
@@ -1073,26 +931,29 @@ services:
|
||||
# Qdrant vector store.
|
||||
# (if used, you need to set VECTOR_STORE to qdrant in the api & worker service.)
|
||||
qdrant:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/qdrant.env
|
||||
required: false
|
||||
- ./envs/vectorstores/qdrant.defaults
|
||||
image: langgenius/qdrant:v1.8.3
|
||||
profiles:
|
||||
- qdrant
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/qdrant:/qdrant/storage
|
||||
environment:
|
||||
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
|
||||
|
||||
# The Couchbase vector store.
|
||||
couchbase-server:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/couchbase.env
|
||||
required: false
|
||||
- ./envs/vectorstores/couchbase.defaults
|
||||
build: ./couchbase-server
|
||||
profiles:
|
||||
- couchbase
|
||||
restart: always
|
||||
environment:
|
||||
- CLUSTER_NAME=dify_search
|
||||
- COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_USER:-Administrator}
|
||||
- COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_PASSWORD:-password}
|
||||
- COUCHBASE_BUCKET=${COUCHBASE_BUCKET_NAME:-Embeddings}
|
||||
- COUCHBASE_BUCKET_RAMSIZE=512
|
||||
- COUCHBASE_RAM_SIZE=2048
|
||||
- COUCHBASE_EVENTING_RAM_SIZE=512
|
||||
@@ -1112,7 +973,7 @@ services:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"curl -s -f -u Administrator:password http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1",
|
||||
"curl -s -f -u \"$$COUCHBASE_ADMINISTRATOR_USERNAME:$$COUCHBASE_ADMINISTRATOR_PASSWORD\" http://localhost:8091/pools/default/buckets | grep -q '\\[{' || exit 1",
|
||||
]
|
||||
interval: 10s
|
||||
retries: 10
|
||||
@@ -1121,21 +982,14 @@ services:
|
||||
|
||||
# The pgvector vector database.
|
||||
pgvector:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/pgvector.env
|
||||
required: false
|
||||
- ./envs/vectorstores/pgvector.defaults
|
||||
image: pgvector/pgvector:pg16
|
||||
profiles:
|
||||
- pgvector
|
||||
restart: always
|
||||
environment:
|
||||
PGUSER: ${PGVECTOR_PGUSER:-postgres}
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD: ${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB: ${PGVECTOR_POSTGRES_DB:-dify}
|
||||
# postgres data directory
|
||||
PGDATA: ${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
# pg_bigm module for full text search
|
||||
PG_BIGM: ${PGVECTOR_PG_BIGM:-false}
|
||||
PG_BIGM_VERSION: ${PGVECTOR_PG_BIGM_VERSION:-1.2-20240606}
|
||||
volumes:
|
||||
- ./volumes/pgvector/data:/var/lib/postgresql/data
|
||||
- ./pgvector/docker-entrypoint.sh:/docker-entrypoint.sh
|
||||
@@ -1172,18 +1026,14 @@ services:
|
||||
|
||||
# pgvecto-rs vector store
|
||||
pgvecto-rs:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/pgvecto-rs.env
|
||||
required: false
|
||||
- ./envs/vectorstores/pgvecto-rs.defaults
|
||||
image: tensorchord/pgvecto-rs:pg16-v0.3.0
|
||||
profiles:
|
||||
- pgvecto-rs
|
||||
restart: always
|
||||
environment:
|
||||
PGUSER: ${PGVECTOR_PGUSER:-postgres}
|
||||
# The password for the default postgres user.
|
||||
POSTGRES_PASSWORD: ${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
# The name of the default postgres database.
|
||||
POSTGRES_DB: ${PGVECTOR_POSTGRES_DB:-dify}
|
||||
# postgres data directory
|
||||
PGDATA: ${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
volumes:
|
||||
- ./volumes/pgvecto_rs/data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
@@ -1194,19 +1044,23 @@ services:
|
||||
|
||||
# Chroma vector database
|
||||
chroma:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/chroma.env
|
||||
required: false
|
||||
- ./envs/vectorstores/chroma.defaults
|
||||
image: ghcr.io/chroma-core/chroma:0.5.20
|
||||
profiles:
|
||||
- chroma
|
||||
restart: always
|
||||
volumes:
|
||||
- ./volumes/chroma:/chroma/chroma
|
||||
environment:
|
||||
CHROMA_SERVER_AUTHN_CREDENTIALS: ${CHROMA_SERVER_AUTHN_CREDENTIALS:-difyai123456}
|
||||
CHROMA_SERVER_AUTHN_PROVIDER: ${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
IS_PERSISTENT: ${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
|
||||
# InterSystems IRIS vector database
|
||||
iris:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/iris.env
|
||||
required: false
|
||||
- ./envs/vectorstores/iris.defaults
|
||||
image: containers.intersystems.com/intersystems/iris-community:2025.3
|
||||
profiles:
|
||||
- iris
|
||||
@@ -1223,11 +1077,14 @@ services:
|
||||
entrypoint: ["/custom-entrypoint.sh"]
|
||||
tty: true
|
||||
environment:
|
||||
TZ: ${IRIS_TIMEZONE:-UTC}
|
||||
ISC_DATA_DIRECTORY: /durable/iris
|
||||
|
||||
# Oracle vector database
|
||||
oracle:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/oracle.env
|
||||
required: false
|
||||
- ./envs/vectorstores/oracle.defaults
|
||||
image: container-registry.oracle.com/database/free:latest
|
||||
profiles:
|
||||
- oracle
|
||||
@@ -1237,21 +1094,19 @@ services:
|
||||
type: volume
|
||||
target: /opt/oracle/oradata
|
||||
- ./startupscripts:/opt/oracle/scripts/startup
|
||||
environment:
|
||||
ORACLE_PWD: ${ORACLE_PWD:-Dify123456}
|
||||
ORACLE_CHARACTERSET: ${ORACLE_CHARACTERSET:-AL32UTF8}
|
||||
|
||||
# Milvus vector database services
|
||||
etcd:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/etcd.env
|
||||
required: false
|
||||
- ./envs/infrastructure/etcd.defaults
|
||||
container_name: milvus-etcd
|
||||
image: quay.io/coreos/etcd:v3.5.5
|
||||
profiles:
|
||||
- milvus
|
||||
environment:
|
||||
ETCD_AUTO_COMPACTION_MODE: ${ETCD_AUTO_COMPACTION_MODE:-revision}
|
||||
ETCD_AUTO_COMPACTION_RETENTION: ${ETCD_AUTO_COMPACTION_RETENTION:-1000}
|
||||
ETCD_QUOTA_BACKEND_BYTES: ${ETCD_QUOTA_BACKEND_BYTES:-4294967296}
|
||||
ETCD_SNAPSHOT_COUNT: ${ETCD_SNAPSHOT_COUNT:-50000}
|
||||
volumes:
|
||||
- ./volumes/milvus/etcd:/etcd
|
||||
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
|
||||
@@ -1264,13 +1119,16 @@ services:
|
||||
- milvus
|
||||
|
||||
minio:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/minio.env
|
||||
required: false
|
||||
- ./envs/infrastructure/minio.defaults
|
||||
container_name: milvus-minio
|
||||
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
|
||||
profiles:
|
||||
- milvus
|
||||
environment:
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
|
||||
volumes:
|
||||
- ./volumes/milvus/minio:/minio_data
|
||||
command: minio server /minio_data --console-address ":9001"
|
||||
@@ -1283,15 +1141,17 @@ services:
|
||||
- milvus
|
||||
|
||||
milvus-standalone:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/milvus.env
|
||||
required: false
|
||||
- path: ./envs/infrastructure/milvus-standalone.env
|
||||
required: false
|
||||
- ./envs/infrastructure/milvus-standalone.defaults
|
||||
container_name: milvus-standalone
|
||||
image: milvusdb/milvus:v2.6.3
|
||||
profiles:
|
||||
- milvus
|
||||
command: ["milvus", "run", "standalone"]
|
||||
environment:
|
||||
ETCD_ENDPOINTS: ${ETCD_ENDPOINTS:-etcd:2379}
|
||||
MINIO_ADDRESS: ${MINIO_ADDRESS:-minio:9000}
|
||||
common.security.authorizationEnabled: ${MILVUS_AUTHORIZATION_ENABLED:-true}
|
||||
volumes:
|
||||
- ./volumes/milvus/milvus:/var/lib/milvus
|
||||
healthcheck:
|
||||
@@ -1311,15 +1171,14 @@ services:
|
||||
|
||||
# Opensearch vector database
|
||||
opensearch:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/opensearch.env
|
||||
required: false
|
||||
- ./envs/vectorstores/opensearch.defaults
|
||||
container_name: opensearch
|
||||
image: opensearchproject/opensearch:latest
|
||||
profiles:
|
||||
- opensearch
|
||||
environment:
|
||||
discovery.type: ${OPENSEARCH_DISCOVERY_TYPE:-single-node}
|
||||
bootstrap.memory_lock: ${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true}
|
||||
OPENSEARCH_JAVA_OPTS: -Xms${OPENSEARCH_JAVA_OPTS_MIN:-512m} -Xmx${OPENSEARCH_JAVA_OPTS_MAX:-1024m}
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD: ${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-Qazwsxedc!@#123}
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: ${OPENSEARCH_MEMLOCK_SOFT:--1}
|
||||
@@ -1348,16 +1207,17 @@ services:
|
||||
|
||||
# opengauss vector database.
|
||||
opengauss:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/opengauss.env
|
||||
required: false
|
||||
- ./envs/vectorstores/opengauss.defaults
|
||||
image: opengauss/opengauss:7.0.0-RC1
|
||||
profiles:
|
||||
- opengauss
|
||||
privileged: true
|
||||
restart: always
|
||||
environment:
|
||||
GS_USERNAME: ${OPENGAUSS_USER:-postgres}
|
||||
GS_PASSWORD: ${OPENGAUSS_PASSWORD:-Dify@123}
|
||||
GS_PORT: ${OPENGAUSS_PORT:-6600}
|
||||
GS_DB: ${OPENGAUSS_DATABASE:-dify}
|
||||
volumes:
|
||||
- ./volumes/opengauss/data:/var/lib/opengauss/data
|
||||
healthcheck:
|
||||
@@ -1398,18 +1258,17 @@ services:
|
||||
# https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html
|
||||
# https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-prod-prerequisites
|
||||
elasticsearch:
|
||||
env_file:
|
||||
- path: ./envs/vectorstores/elasticsearch.env
|
||||
required: false
|
||||
- ./envs/vectorstores/elasticsearch.defaults
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:8.14.3
|
||||
container_name: elasticsearch
|
||||
profiles:
|
||||
- elasticsearch
|
||||
- elasticsearch-ja
|
||||
restart: always
|
||||
volumes:
|
||||
- ./elasticsearch/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
- dify_es01_data:/usr/share/elasticsearch/data
|
||||
environment:
|
||||
ELASTIC_PASSWORD: ${ELASTICSEARCH_PASSWORD:-elastic}
|
||||
VECTOR_STORE: ${VECTOR_STORE:-}
|
||||
cluster.name: dify-es-cluster
|
||||
node.name: dify-es0
|
||||
discovery.type: single-node
|
||||
@@ -1417,6 +1276,11 @@ services:
|
||||
xpack.security.enabled: "true"
|
||||
xpack.security.enrollment.enabled: "false"
|
||||
xpack.security.http.ssl.enabled: "false"
|
||||
# Backend selection also controls the Japanese analyzer installed by the entrypoint.
|
||||
VECTOR_STORE: ${VECTOR_STORE:-}
|
||||
volumes:
|
||||
- ./elasticsearch/docker-entrypoint.sh:/docker-entrypoint-mount.sh
|
||||
- dify_es01_data:/usr/share/elasticsearch/data
|
||||
ports:
|
||||
- ${ELASTICSEARCH_PORT:-9200}:9200
|
||||
deploy:
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# Defaults for api. Copy this file to api.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# MODE is selected by the Compose service.
|
||||
# Optional SaaS network-policy control plane and current-IP preview trust.
|
||||
# NETWORK_ACCESS_API_URL=
|
||||
# Comma-separated proxy CIDRs; empty disables Cloud IP previews. The edge
|
||||
# must sanitize/append XFF and the trust boundary must match Gateway.
|
||||
# NETWORK_ACCESS_TRUSTED_PROXY_CIDRS=
|
||||
API_SENTRY_DSN=${API_SENTRY_DSN:-}
|
||||
API_SENTRY_TRACES_SAMPLE_RATE=${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
API_SENTRY_PROFILES_SAMPLE_RATE=${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
API_WEBSOCKET_WORKER_AMOUNT=${API_WEBSOCKET_WORKER_AMOUNT:-1}
|
||||
API_WEBSOCKET_WORKER_CLASS=${API_WEBSOCKET_WORKER_CLASS:-geventwebsocket.gunicorn.workers.GeventWebSocketWorker}
|
||||
API_WEBSOCKET_WORKER_CONNECTIONS=${API_WEBSOCKET_WORKER_CONNECTIONS:-1000}
|
||||
API_WEBSOCKET_GUNICORN_TIMEOUT=${API_WEBSOCKET_GUNICORN_TIMEOUT:-360}
|
||||
# Set EXPOSE_PLUGIN_DEBUGGING_HOST and EXPOSE_PLUGIN_DEBUGGING_PORT in docker/.env
|
||||
# so the API connection and Compose port mapping use the same address.
|
||||
PLUGIN_MAX_PACKAGE_SIZE=${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_DAEMON_TIMEOUT=${PLUGIN_DAEMON_TIMEOUT:-600.0}
|
||||
# Set PLUGIN_DIFY_INNER_API_KEY in docker/.env; all callers must share the API's inner credential.
|
||||
# Optional server-side secret mixed into account password hashes. Leave empty to keep the legacy hashing.
|
||||
# WARNING: setting, changing, or removing this value changes every password hash and existing passwords
|
||||
# will stop working. Do not change it casually.
|
||||
# Use a high-entropy random value, e.g. generate one with `openssl rand -base64 32`.
|
||||
# Keep it in this file rather than docker/.env, which is also loaded by plugin_daemon and agent_backend.
|
||||
# PASSWORD_PEPPER=
|
||||
# Client deadline for converting a Binding file to a ToolFile through the Agent backend.
|
||||
# AGENT_BACKEND_BINDING_FILE_DOWNLOAD_TIMEOUT_SECONDS=240
|
||||
# KNOWLEDGE_FS_ENABLED=${KNOWLEDGE_FS_ENABLED:-false}
|
||||
# Explicitly bypass the Community edition gate for development deployments.
|
||||
# KNOWLEDGE_FS_COMMUNITY_DEV_ENABLED=${KNOWLEDGE_FS_COMMUNITY_DEV_ENABLED:-false}
|
||||
# Production deployments require HTTPS; plain HTTP is limited to non-production or loopback.
|
||||
# KNOWLEDGE_FS_BASE_URL=
|
||||
# Optional trusted direct origin for KnowledgeFS internal requests.
|
||||
# KNOWLEDGE_FS_DIRECT_ORIGIN=
|
||||
# KNOWLEDGE_FS_LIFECYCLE_WORKER_ENABLED=false
|
||||
# KNOWLEDGE_FS_INTEGRATED_PROVISION_READY=false
|
||||
# KNOWLEDGE_FS_LEGACY_ACL_FREEZE_READY=false
|
||||
# KNOWLEDGE_FS_LIFECYCLE_POLL_INTERVAL_SECONDS=15
|
||||
# KNOWLEDGE_FS_LIFECYCLE_LEASE_SECONDS=60
|
||||
# KNOWLEDGE_FS_LIFECYCLE_BATCH_SIZE=25
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_ENABLED=false
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_SIGNING_KID=
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_PRIVATE_KEY_PEM=
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_PREVIOUS_PUBLIC_JWKS=
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_ISSUER=dify-control-plane
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_AUDIENCE=knowledge-fs
|
||||
# KNOWLEDGE_FS_CAPABILITY_V2_MAX_TTL_SECONDS=60
|
||||
# KNOWLEDGE_FS_JWKS_CACHE_MAX_AGE_SECONDS=300
|
||||
# KNOWLEDGE_FS_PRODUCT_MAX_RESPONSE_BYTES=4194304
|
||||
# KNOWLEDGE_FS_TIMEOUT_SECONDS=10
|
||||
# Retrieval tests have a 60-second KnowledgeFS execution budget and need transport headroom.
|
||||
# KNOWLEDGE_FS_RETRIEVAL_TEST_TIMEOUT_SECONDS=75
|
||||
|
||||
# Lifetime in days of difyctl (OAuth device flow) tokens, 1-365; out-of-range values are clamped
|
||||
# OAUTH_TTL_DAYS=14
|
||||
|
||||
# Cloudflare Turnstile server-side verification for Dify Cloud sign-in
|
||||
# TURNSTILE_SECRET_KEY=
|
||||
# TURNSTILE_ALLOWED_HOSTNAMES=
|
||||
# TURNSTILE_EMAIL_CODE_VERIFY_REQUIRED=false
|
||||
DIFY_AGENT_API_TOKEN=${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
AGENT_BACKEND_BASE_URL=${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
# The bundled Nginx supplies a verified client IP; keep direct API callers trusted.
|
||||
# Compose enables forwarded headers here; the bare application default is false.
|
||||
# Override in api.env or docker/.env. See docker/README.md#client-ip-and-trusted-proxies
|
||||
# before exposing the API directly.
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED=${RESPECT_XFORWARD_HEADERS_ENABLED:-true}
|
||||
CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/1}
|
||||
|
||||
# API server and OpenAPI settings
|
||||
# DIFY_BIND_ADDRESS=0.0.0.0
|
||||
# DIFY_PORT=5001
|
||||
# SERVER_WORKER_AMOUNT=1
|
||||
# SERVER_WORKER_CONNECTIONS=10
|
||||
# Must stay above the idle connection reuse window of the HTTP clients that
|
||||
# pool connections to this server. Node's global fetch (undici) keeps a socket
|
||||
# idle for 4s before dropping it, so a shorter value here lets the server close
|
||||
# a connection the client still considers reusable, which surfaces as
|
||||
# intermittent ECONNRESET on server-side rendering. 0 disables keep-alive.
|
||||
# GUNICORN_KEEP_ALIVE=10
|
||||
# WEBSOCKET_MAX_HTTP_BUFFER_SIZE=10485760
|
||||
# SWAGGER_UI_ENABLED=false
|
||||
# SWAGGER_UI_PATH=/swagger-ui.html
|
||||
# OPENAPI_ENABLED=false
|
||||
# OPENAPI_CORS_ALLOW_ORIGINS=
|
||||
# OPENAPI_KNOWN_CLIENT_IDS=difyctl
|
||||
# OPENAPI_RATE_LIMIT_PER_TOKEN=60
|
||||
# DEVICE_FLOW_APPROVE_RATE_LIMIT_PER_HOUR=10
|
||||
# ENABLE_OAUTH_BEARER=false
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
AGENT_BACKEND_API_TOKEN=${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
INNER_API_KEY_FOR_PLUGIN=${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
PLUGIN_REMOTE_INSTALL_HOST=${EXPOSE_PLUGIN_DEBUGGING_HOST:-localhost}
|
||||
PLUGIN_REMOTE_INSTALL_PORT=${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}
|
||||
SENTRY_DSN=${API_SENTRY_DSN:-}
|
||||
SENTRY_PROFILES_SAMPLE_RATE=${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_TRACES_SAMPLE_RATE=${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
@@ -1,59 +0,0 @@
|
||||
# ------------------------------
|
||||
# Api Configuration
|
||||
# ------------------------------
|
||||
|
||||
MODE=api
|
||||
# Optional SaaS network-policy control plane and current-IP preview trust.
|
||||
NETWORK_ACCESS_API_URL=
|
||||
# Comma-separated proxy CIDRs; empty disables Cloud IP previews. The edge
|
||||
# must sanitize/append XFF and the trust boundary must match Gateway.
|
||||
NETWORK_ACCESS_TRUSTED_PROXY_CIDRS=
|
||||
SENTRY_DSN=
|
||||
SENTRY_TRACES_SAMPLE_RATE=1.0
|
||||
SENTRY_PROFILES_SAMPLE_RATE=1.0
|
||||
PLUGIN_REMOTE_INSTALL_HOST=localhost
|
||||
PLUGIN_REMOTE_INSTALL_PORT=5003
|
||||
PLUGIN_MAX_PACKAGE_SIZE=52428800
|
||||
PLUGIN_DAEMON_TIMEOUT=600.0
|
||||
INNER_API_KEY_FOR_PLUGIN=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
|
||||
# Optional server-side secret mixed into account password hashes. Leave empty to keep the legacy hashing.
|
||||
# WARNING: setting, changing, or removing this value changes every password hash and existing passwords
|
||||
# will stop working. Do not change it casually.
|
||||
# Use a high-entropy random value, e.g. generate one with `openssl rand -base64 32`.
|
||||
# Keep it in this file rather than docker/.env, which is also loaded by plugin_daemon and agent_backend.
|
||||
PASSWORD_PEPPER=
|
||||
# Client deadline for converting a Binding file to a ToolFile through the Agent backend.
|
||||
AGENT_BACKEND_BINDING_FILE_DOWNLOAD_TIMEOUT_SECONDS=240
|
||||
KNOWLEDGE_FS_ENABLED=${KNOWLEDGE_FS_ENABLED:-false}
|
||||
# Explicitly bypass the Community edition gate for development deployments.
|
||||
KNOWLEDGE_FS_COMMUNITY_DEV_ENABLED=${KNOWLEDGE_FS_COMMUNITY_DEV_ENABLED:-false}
|
||||
# Production deployments require HTTPS; plain HTTP is limited to non-production or loopback.
|
||||
KNOWLEDGE_FS_BASE_URL=
|
||||
# Optional trusted direct origin for KnowledgeFS internal requests.
|
||||
KNOWLEDGE_FS_DIRECT_ORIGIN=
|
||||
KNOWLEDGE_FS_LIFECYCLE_WORKER_ENABLED=false
|
||||
KNOWLEDGE_FS_INTEGRATED_PROVISION_READY=false
|
||||
KNOWLEDGE_FS_LEGACY_ACL_FREEZE_READY=false
|
||||
KNOWLEDGE_FS_LIFECYCLE_POLL_INTERVAL_SECONDS=15
|
||||
KNOWLEDGE_FS_LIFECYCLE_LEASE_SECONDS=60
|
||||
KNOWLEDGE_FS_LIFECYCLE_BATCH_SIZE=25
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_ENABLED=false
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_SIGNING_KID=
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_PRIVATE_KEY_PEM=
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_PREVIOUS_PUBLIC_JWKS=
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_ISSUER=dify-control-plane
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_AUDIENCE=knowledge-fs
|
||||
KNOWLEDGE_FS_CAPABILITY_V2_MAX_TTL_SECONDS=60
|
||||
KNOWLEDGE_FS_JWKS_CACHE_MAX_AGE_SECONDS=300
|
||||
KNOWLEDGE_FS_PRODUCT_MAX_RESPONSE_BYTES=4194304
|
||||
KNOWLEDGE_FS_TIMEOUT_SECONDS=10
|
||||
# Retrieval tests have a 60-second KnowledgeFS execution budget and need transport headroom.
|
||||
KNOWLEDGE_FS_RETRIEVAL_TEST_TIMEOUT_SECONDS=75
|
||||
|
||||
# Lifetime in days of difyctl (OAuth device flow) tokens, 1-365; out-of-range values are clamped
|
||||
# OAUTH_TTL_DAYS=14
|
||||
|
||||
# Cloudflare Turnstile server-side verification for Dify Cloud sign-in
|
||||
TURNSTILE_SECRET_KEY=
|
||||
TURNSTILE_ALLOWED_HOSTNAMES=
|
||||
TURNSTILE_EMAIL_CODE_VERIFY_REQUIRED=false
|
||||
@@ -0,0 +1,132 @@
|
||||
# Defaults for agent_backend. Copy this file to dify-agent.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# AGENT_BACKEND_BASE_URL=http://agent_backend:5050
|
||||
# Set this in docker/.env to share the same control-plane token with API and workers.
|
||||
# Replace the development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
DIFY_AGENT_API_TOKEN=${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
|
||||
# Leave empty to derive from REDIS_PASSWORD in Docker Compose.
|
||||
DIFY_AGENT_REDIS_URL=${DIFY_AGENT_REDIS_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@redis:6379/2}
|
||||
# DIFY_AGENT_REDIS_PREFIX=dify-agent
|
||||
# DIFY_AGENT_SHUTDOWN_GRACE_SECONDS=30
|
||||
# DIFY_AGENT_RUN_RETENTION_SECONDS=7200
|
||||
# DIFY_AGENT_RUN_EVENT_STREAM_MAX_LENGTH=5000
|
||||
# DIFY_AGENT_STREAM_TEXT_DELTA_COALESCING_ENABLED=true
|
||||
# DIFY_AGENT_STREAM_TEXT_DELTA_FLUSH_INTERVAL_MS=100
|
||||
# DIFY_AGENT_STREAM_TEXT_DELTA_MAX_CHARS=4096
|
||||
# Internal deadline for the Agent Backend model/tool loop. The effective run
|
||||
# limit is whichever expires first: this value or the relevant API/Workflow
|
||||
# outer execution limit. To allow every path to run for one hour, also set
|
||||
# APP_MAX_EXECUTION_TIME and WORKFLOW_MAX_EXECUTION_TIME to at least 3600.
|
||||
# DIFY_AGENT_RUN_TIMEOUT_SECONDS=3600
|
||||
# DIFY_AGENT_BINDING_FILE_DOWNLOAD_COMMAND_TIMEOUT_SECONDS=210
|
||||
|
||||
# Shared outbound HTTP client timeouts and connection limits.
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_CONNECT_TIMEOUT=10
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_READ_TIMEOUT=600
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_WRITE_TIMEOUT=30
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_POOL_TIMEOUT=10
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_MAX_CONNECTIONS=100
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
# DIFY_AGENT_OUTBOUND_HTTP_KEEPALIVE_EXPIRY=30
|
||||
|
||||
# DIFY_AGENT_TRAJECTORY_ENABLED=false
|
||||
# Collect API-issued application traces into the Dify inner API inbox.
|
||||
# DIFY_AGENT_APPLICATION_TRACING_ENABLED=false
|
||||
# DIFY_AGENT_TRAJECTORY_OTLP_TRACES_ENDPOINT=
|
||||
# DIFY_AGENT_TRAJECTORY_OTLP_HEADERS={}
|
||||
# DIFY_AGENT_TRAJECTORY_SERVICE_NAME=dify-agent-trajectory
|
||||
# DIFY_AGENT_TRAJECTORY_INCLUDE_CONTENT=false
|
||||
# DIFY_AGENT_TRAJECTORY_TRACE_CONTEXT_MODE=isolated
|
||||
# DIFY_AGENT_TRAJECTORY_MAX_QUEUE_SIZE=2048
|
||||
# DIFY_AGENT_TRAJECTORY_MAX_EXPORT_BATCH_SIZE=512
|
||||
# DIFY_AGENT_TRAJECTORY_SCHEDULE_DELAY_MS=5000
|
||||
# DIFY_AGENT_TRAJECTORY_EXPORT_TIMEOUT_MS=5000
|
||||
|
||||
# LOGFIRE_CONSOLE=false
|
||||
|
||||
# Leave empty to derive from PLUGIN_DAEMON_URL and PLUGIN_DAEMON_KEY in Docker Compose.
|
||||
# Set PLUGIN_DAEMON_KEY in docker/.env when using the bundled daemon; keep the key expression below unchanged.
|
||||
DIFY_AGENT_PLUGIN_DAEMON_URL=${DIFY_AGENT_PLUGIN_DAEMON_URL:-${PLUGIN_DAEMON_URL:-http://plugin_daemon:5002}}
|
||||
DIFY_AGENT_PLUGIN_DAEMON_API_KEY=${DIFY_AGENT_PLUGIN_DAEMON_API_KEY:-${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}}
|
||||
|
||||
# Leave empty to derive from PLUGIN_DIFY_INNER_API_URL and PLUGIN_DIFY_INNER_API_KEY in Docker Compose.
|
||||
# DIFY_AGENT_INNER_API_KEY must match API/worker INNER_API_KEY_FOR_PLUGIN, not INNER_API_KEY.
|
||||
# Set PLUGIN_DIFY_INNER_API_KEY in docker/.env; keep the key expression below unchanged for the bundled API.
|
||||
DIFY_AGENT_INNER_API_URL=${DIFY_AGENT_INNER_API_URL:-${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}}
|
||||
DIFY_AGENT_INNER_API_KEY=${DIFY_AGENT_INNER_API_KEY:-${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}}
|
||||
|
||||
# Select exactly one coherent Home Snapshot + Sandbox backend.
|
||||
DIFY_AGENT_RUNTIME_BACKEND=${DIFY_AGENT_RUNTIME_BACKEND:-local}
|
||||
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT=${DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT:-${DIFY_AGENT_SHELLCTL_ENTRYPOINT:-http://local_sandbox:5004}}
|
||||
# Required nonblank secret for Local. Set in docker/.env to also configure shellctl.
|
||||
DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN=${DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN:-${DIFY_AGENT_SHELLCTL_AUTH_TOKEN:-}}
|
||||
# E2B_API_KEY and E2B_API_TOKEN remain accepted as deployment-level fallbacks.
|
||||
DIFY_AGENT_E2B_API_KEY=${DIFY_AGENT_E2B_API_KEY:-${E2B_API_KEY:-${E2B_API_TOKEN:-}}}
|
||||
DIFY_AGENT_E2B_TEMPLATE=${DIFY_AGENT_E2B_TEMPLATE:-difys-default-team/dify-agent-local-sandbox}
|
||||
# RuntimeLease active limit; its default matches the independently configurable Agent run deadline.
|
||||
# DIFY_AGENT_E2B_ACTIVE_TIMEOUT_SECONDS=3600
|
||||
# DIFY_AGENT_E2B_SHELLCTL_PORT=5004
|
||||
|
||||
# Independent sandbox usage ledger. API owns fixed activation time T0; no backfill.
|
||||
# Enable only with matching API metering project settings and events API access.
|
||||
# Celery Beat in the API triggers a protected one-shot collection endpoint.
|
||||
# No operation logging, Agent polling loop, or collector Redis leader.
|
||||
# Collection requires the existing DIFY_AGENT_API_TOKEN to be configured.
|
||||
# DIFY_AGENT_SANDBOX_METERING_ENABLED=false
|
||||
# DIFY_AGENT_E2B_PROJECT_ID=
|
||||
# DIFY_AGENT_SANDBOX_METERING_OVERLAP_SECONDS=900
|
||||
# DIFY_AGENT_SANDBOX_METERING_FULL_SCAN_INTERVAL_SECONDS=3600
|
||||
# DIFY_AGENT_SANDBOX_METERING_MAX_PAGES=1000
|
||||
|
||||
# OpenShell backend (DIFY_AGENT_RUNTIME_BACKEND=openshell): sandboxes run on a
|
||||
# self-hosted NVIDIA OpenShell gateway. Setup and validation:
|
||||
# dify-agent/docs/dify-agent/guide/openshell.md
|
||||
# gRPC endpoint as host:port (no scheme), e.g. localhost:17670.
|
||||
# DIFY_AGENT_OPENSHELL_GATEWAY_ENDPOINT=
|
||||
# One workspace and one dedicated shared volume per tenant in production.
|
||||
# DIFY_AGENT_OPENSHELL_WORKSPACE=default
|
||||
# Auth: an OIDC bearer token, or mTLS bundle paths mounted into agent_backend.
|
||||
# DIFY_AGENT_OPENSHELL_BEARER_TOKEN=
|
||||
# DIFY_AGENT_OPENSHELL_TLS_CA_PATH=
|
||||
# DIFY_AGENT_OPENSHELL_TLS_CLIENT_CERT_PATH=
|
||||
# DIFY_AGENT_OPENSHELL_TLS_CLIENT_KEY_PATH=
|
||||
# Set true only for plaintext local-dev gateways.
|
||||
# DIFY_AGENT_OPENSHELL_INSECURE=false
|
||||
# Required: build the runtime image yourself from this checkout; do not rely on a published latest tag.
|
||||
# From the repository root (the directory containing dify-agent-runtime/):
|
||||
# docker build -f dify-agent-runtime/docker/Dockerfile -t dify-agent-runtime:latest dify-agent-runtime
|
||||
# The image must include shellctl and iproute2. This value must match the built image tag.
|
||||
# Build into the gateway's Docker daemon, or push to a registry it can pull from and use that image reference.
|
||||
# DIFY_AGENT_OPENSHELL_SANDBOX_IMAGE=docker.io/library/dify-agent-runtime:latest
|
||||
# Required JSON driver_config mounting the operator-owned shared volume;
|
||||
# one-time volume initialization and driver examples live in the guide.
|
||||
# DIFY_AGENT_OPENSHELL_DRIVER_CONFIG=
|
||||
# DIFY_AGENT_OPENSHELL_SHARED_MOUNT_PATH=/mnt/dify-agent-shared
|
||||
# Optional comma-separated host:port egress allowlist (no scheme or path).
|
||||
# Empty sends no network policy (gateway/driver default egress); when set,
|
||||
# sandbox egress is enforced to exactly these endpoints — include the Agent
|
||||
# Stub and files endpoints, e.g. agent.example.com:443,dify.example.com:443.
|
||||
# DIFY_AGENT_OPENSHELL_EGRESS_ALLOW=
|
||||
# Required. shellctl path isolation stays off (sandbox Landlock is authoritative).
|
||||
# DIFY_AGENT_OPENSHELL_SHELLCTL_AUTH_TOKEN=
|
||||
# DIFY_AGENT_OPENSHELL_SHELLCTL_PORT=5004
|
||||
# DIFY_AGENT_OPENSHELL_READY_TIMEOUT_SECONDS=300
|
||||
# DIFY_AGENT_OPENSHELL_EXEC_TIMEOUT_SECONDS=120
|
||||
# Sandbox-reachable Dify API base for signed /files/* transfers.
|
||||
DIFY_AGENT_SANDBOX_FILES_BASE_URL=${DIFY_AGENT_SANDBOX_FILES_BASE_URL:-http://api:5001}
|
||||
# Maximum Agent Stub upload size in MiB; forwarded to Dify API as a signed byte limit.
|
||||
# DIFY_AGENT_STUB_UPLOAD_FILE_SIZE_LIMIT=50
|
||||
DIFY_AGENT_STUB_API_BASE_URL=${DIFY_AGENT_STUB_API_BASE_URL:-http://agent_backend:5050/agent-stub}
|
||||
# This is security-sensitive: it derives the JWE encryption key for Agent Stub bearer tokens.
|
||||
# Replace this development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
DIFY_AGENT_SERVER_SECRET_KEY=${DIFY_AGENT_SERVER_SECRET_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY}
|
||||
|
||||
# JSON array of regex patterns to redact from shell output shown to the agent.
|
||||
# The JWE token value is always redacted regardless of this setting.
|
||||
# Example: DIFY_AGENT_SHELL_REDACT_PATTERNS=["sk-[A-Za-z0-9]+","ghp_[A-Za-z0-9]{36}"]
|
||||
# DIFY_AGENT_SHELL_REDACT_PATTERNS=
|
||||
@@ -1,132 +0,0 @@
|
||||
# ------------------------------
|
||||
# Dify Agent Backend Configuration
|
||||
# ------------------------------
|
||||
|
||||
AGENT_BACKEND_BASE_URL=http://agent_backend:5050
|
||||
# Set this in docker/.env to share the same control-plane token with API and workers.
|
||||
# Replace the development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
# DIFY_AGENT_API_TOKEN=dify-agent-run-token-for-dev-only
|
||||
|
||||
# Leave empty to derive from REDIS_PASSWORD in Docker Compose.
|
||||
DIFY_AGENT_REDIS_URL=
|
||||
DIFY_AGENT_REDIS_PREFIX=dify-agent
|
||||
DIFY_AGENT_SHUTDOWN_GRACE_SECONDS=30
|
||||
DIFY_AGENT_RUN_RETENTION_SECONDS=7200
|
||||
DIFY_AGENT_RUN_EVENT_STREAM_MAX_LENGTH=5000
|
||||
DIFY_AGENT_STREAM_TEXT_DELTA_COALESCING_ENABLED=true
|
||||
DIFY_AGENT_STREAM_TEXT_DELTA_FLUSH_INTERVAL_MS=100
|
||||
DIFY_AGENT_STREAM_TEXT_DELTA_MAX_CHARS=4096
|
||||
# Internal deadline for the Agent Backend model/tool loop. The effective run
|
||||
# limit is whichever expires first: this value or the relevant API/Workflow
|
||||
# outer execution limit. To allow every path to run for one hour, also set
|
||||
# APP_MAX_EXECUTION_TIME and WORKFLOW_MAX_EXECUTION_TIME to at least 3600.
|
||||
DIFY_AGENT_RUN_TIMEOUT_SECONDS=3600
|
||||
DIFY_AGENT_BINDING_FILE_DOWNLOAD_COMMAND_TIMEOUT_SECONDS=210
|
||||
|
||||
# Shared outbound HTTP client timeouts and connection limits.
|
||||
DIFY_AGENT_OUTBOUND_HTTP_CONNECT_TIMEOUT=10
|
||||
DIFY_AGENT_OUTBOUND_HTTP_READ_TIMEOUT=600
|
||||
DIFY_AGENT_OUTBOUND_HTTP_WRITE_TIMEOUT=30
|
||||
DIFY_AGENT_OUTBOUND_HTTP_POOL_TIMEOUT=10
|
||||
DIFY_AGENT_OUTBOUND_HTTP_MAX_CONNECTIONS=100
|
||||
DIFY_AGENT_OUTBOUND_HTTP_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
DIFY_AGENT_OUTBOUND_HTTP_KEEPALIVE_EXPIRY=30
|
||||
|
||||
DIFY_AGENT_TRAJECTORY_ENABLED=false
|
||||
# Collect API-issued application traces into the Dify inner API inbox.
|
||||
DIFY_AGENT_APPLICATION_TRACING_ENABLED=false
|
||||
DIFY_AGENT_TRAJECTORY_OTLP_TRACES_ENDPOINT=
|
||||
DIFY_AGENT_TRAJECTORY_OTLP_HEADERS={}
|
||||
DIFY_AGENT_TRAJECTORY_SERVICE_NAME=dify-agent-trajectory
|
||||
DIFY_AGENT_TRAJECTORY_INCLUDE_CONTENT=false
|
||||
DIFY_AGENT_TRAJECTORY_TRACE_CONTEXT_MODE=isolated
|
||||
DIFY_AGENT_TRAJECTORY_MAX_QUEUE_SIZE=2048
|
||||
DIFY_AGENT_TRAJECTORY_MAX_EXPORT_BATCH_SIZE=512
|
||||
DIFY_AGENT_TRAJECTORY_SCHEDULE_DELAY_MS=5000
|
||||
DIFY_AGENT_TRAJECTORY_EXPORT_TIMEOUT_MS=5000
|
||||
|
||||
LOGFIRE_CONSOLE=false
|
||||
|
||||
# Leave empty to derive from PLUGIN_DAEMON_URL and PLUGIN_DAEMON_KEY in Docker Compose.
|
||||
DIFY_AGENT_PLUGIN_DAEMON_URL=
|
||||
DIFY_AGENT_PLUGIN_DAEMON_API_KEY=
|
||||
|
||||
# Leave empty to derive from PLUGIN_DIFY_INNER_API_URL and PLUGIN_DIFY_INNER_API_KEY in Docker Compose.
|
||||
# DIFY_AGENT_INNER_API_KEY must match API/worker INNER_API_KEY_FOR_PLUGIN, not INNER_API_KEY.
|
||||
DIFY_AGENT_INNER_API_URL=
|
||||
DIFY_AGENT_INNER_API_KEY=
|
||||
|
||||
# Select exactly one coherent Home Snapshot + Sandbox backend.
|
||||
DIFY_AGENT_RUNTIME_BACKEND=local
|
||||
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT=http://local_sandbox:5004
|
||||
# Required nonblank secret for Local. Set in the shared Compose interpolation source: shell,
|
||||
# docker/.env, or --env-file. Setting only this service env file is overridden
|
||||
# by Compose's explicit environment value and does not configure shellctl.
|
||||
DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN=
|
||||
# E2B_API_KEY and E2B_API_TOKEN remain accepted as deployment-level fallbacks.
|
||||
DIFY_AGENT_E2B_API_KEY=${DIFY_AGENT_E2B_API_KEY:-${E2B_API_KEY:-${E2B_API_TOKEN:-}}}
|
||||
DIFY_AGENT_E2B_TEMPLATE=difys-default-team/dify-agent-local-sandbox
|
||||
# RuntimeLease active limit; its default matches the independently configurable Agent run deadline.
|
||||
DIFY_AGENT_E2B_ACTIVE_TIMEOUT_SECONDS=3600
|
||||
DIFY_AGENT_E2B_SHELLCTL_PORT=5004
|
||||
|
||||
# Independent sandbox usage ledger. API owns fixed activation time T0; no backfill.
|
||||
# Enable only with matching API metering project settings and events API access.
|
||||
# Celery Beat in the API triggers a protected one-shot collection endpoint.
|
||||
# No operation logging, Agent polling loop, or collector Redis leader.
|
||||
# Collection requires the existing DIFY_AGENT_API_TOKEN to be configured.
|
||||
DIFY_AGENT_SANDBOX_METERING_ENABLED=false
|
||||
DIFY_AGENT_E2B_PROJECT_ID=
|
||||
DIFY_AGENT_SANDBOX_METERING_OVERLAP_SECONDS=900
|
||||
DIFY_AGENT_SANDBOX_METERING_FULL_SCAN_INTERVAL_SECONDS=3600
|
||||
DIFY_AGENT_SANDBOX_METERING_MAX_PAGES=1000
|
||||
|
||||
# OpenShell backend (DIFY_AGENT_RUNTIME_BACKEND=openshell): sandboxes run on a
|
||||
# self-hosted NVIDIA OpenShell gateway. Setup and validation:
|
||||
# dify-agent/docs/dify-agent/guide/openshell.md
|
||||
# gRPC endpoint as host:port (no scheme), e.g. localhost:17670.
|
||||
DIFY_AGENT_OPENSHELL_GATEWAY_ENDPOINT=
|
||||
# One workspace and one dedicated shared volume per tenant in production.
|
||||
DIFY_AGENT_OPENSHELL_WORKSPACE=default
|
||||
# Auth: an OIDC bearer token, or mTLS bundle paths mounted into agent_backend.
|
||||
DIFY_AGENT_OPENSHELL_BEARER_TOKEN=
|
||||
DIFY_AGENT_OPENSHELL_TLS_CA_PATH=
|
||||
DIFY_AGENT_OPENSHELL_TLS_CLIENT_CERT_PATH=
|
||||
DIFY_AGENT_OPENSHELL_TLS_CLIENT_KEY_PATH=
|
||||
# Set true only for plaintext local-dev gateways.
|
||||
DIFY_AGENT_OPENSHELL_INSECURE=false
|
||||
# Required: build the runtime image yourself from this checkout; do not rely on a published latest tag.
|
||||
# From the repository root (the directory containing dify-agent-runtime/):
|
||||
# docker build -f dify-agent-runtime/docker/Dockerfile -t dify-agent-runtime:latest dify-agent-runtime
|
||||
# The image must include shellctl and iproute2. This value must match the built image tag.
|
||||
# Build into the gateway's Docker daemon, or push to a registry it can pull from and use that image reference.
|
||||
DIFY_AGENT_OPENSHELL_SANDBOX_IMAGE=docker.io/library/dify-agent-runtime:latest
|
||||
# Required JSON driver_config mounting the operator-owned shared volume;
|
||||
# one-time volume initialization and driver examples live in the guide.
|
||||
DIFY_AGENT_OPENSHELL_DRIVER_CONFIG=
|
||||
DIFY_AGENT_OPENSHELL_SHARED_MOUNT_PATH=/mnt/dify-agent-shared
|
||||
# Optional comma-separated host:port egress allowlist (no scheme or path).
|
||||
# Empty sends no network policy (gateway/driver default egress); when set,
|
||||
# sandbox egress is enforced to exactly these endpoints — include the Agent
|
||||
# Stub and files endpoints, e.g. agent.example.com:443,dify.example.com:443.
|
||||
DIFY_AGENT_OPENSHELL_EGRESS_ALLOW=
|
||||
# Required. shellctl path isolation stays off (sandbox Landlock is authoritative).
|
||||
DIFY_AGENT_OPENSHELL_SHELLCTL_AUTH_TOKEN=
|
||||
DIFY_AGENT_OPENSHELL_SHELLCTL_PORT=5004
|
||||
DIFY_AGENT_OPENSHELL_READY_TIMEOUT_SECONDS=300
|
||||
DIFY_AGENT_OPENSHELL_EXEC_TIMEOUT_SECONDS=120
|
||||
# Sandbox-reachable Dify API base for signed /files/* transfers.
|
||||
DIFY_AGENT_SANDBOX_FILES_BASE_URL=http://api:5001
|
||||
# Maximum Agent Stub upload size in MiB; forwarded to Dify API as a signed byte limit.
|
||||
DIFY_AGENT_STUB_UPLOAD_FILE_SIZE_LIMIT=50
|
||||
DIFY_AGENT_STUB_API_BASE_URL=http://agent_backend:5050/agent-stub
|
||||
# This is security-sensitive: it derives the JWE encryption key for Agent Stub bearer tokens.
|
||||
# Replace this development default in production.
|
||||
# Generate one with: python -c 'import secrets; print(secrets.token_urlsafe(32))'
|
||||
DIFY_AGENT_SERVER_SECRET_KEY=MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY
|
||||
|
||||
# JSON array of regex patterns to redact from shell output shown to the agent.
|
||||
# The JWE token value is always redacted regardless of this setting.
|
||||
# Example: DIFY_AGENT_SHELL_REDACT_PATTERNS=["sk-[A-Za-z0-9]+","ghp_[A-Za-z0-9]{36}"]
|
||||
DIFY_AGENT_SHELL_REDACT_PATTERNS=
|
||||
@@ -0,0 +1,89 @@
|
||||
# Defaults for plugin_daemon. Copy this file to plugin-daemon.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
DB_PLUGIN_DATABASE=${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||
# PLUGIN_DAEMON_URL=http://plugin_daemon:5002
|
||||
PLUGIN_PPROF_ENABLED=${PLUGIN_PPROF_ENABLED:-false}
|
||||
PLUGIN_DIFY_INNER_API_URL=${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}
|
||||
FORCE_VERIFYING_SIGNATURE=${FORCE_VERIFYING_SIGNATURE:-true}
|
||||
PLUGIN_STDIO_BUFFER_SIZE=${PLUGIN_STDIO_BUFFER_SIZE:-1024}
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE=${PLUGIN_STDIO_MAX_BUFFER_SIZE:-5242880}
|
||||
PLUGIN_PYTHON_ENV_INIT_TIMEOUT=${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT=${PLUGIN_MAX_EXECUTION_TIMEOUT:-600}
|
||||
PLUGIN_DEBUGGING_HOST=${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
# Set PLUGIN_DEBUGGING_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# Set PLUGIN_DAEMON_KEY in docker/.env; API, workers, and Agent must share the daemon's credential.
|
||||
# Set PLUGIN_DIFY_INNER_API_KEY in docker/.env; all callers must share the API's inner credential.
|
||||
PLUGIN_DAEMON_PORT=${PLUGIN_DAEMON_PORT:-5002}
|
||||
PLUGIN_STORAGE_TYPE=${PLUGIN_STORAGE_TYPE:-local}
|
||||
PLUGIN_STORAGE_LOCAL_ROOT=${PLUGIN_STORAGE_LOCAL_ROOT:-/app/storage}
|
||||
PLUGIN_WORKING_PATH=${PLUGIN_WORKING_PATH:-/app/storage/cwd}
|
||||
# Optional: set in docker/.env for Docker/WSL bind-mount permission errors (langgenius/dify#42433).
|
||||
# UV_CACHE_DIR=/tmp/.uv-cache
|
||||
PLUGIN_STORAGE_OSS_BUCKET=${PLUGIN_STORAGE_OSS_BUCKET:-}
|
||||
PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID=${PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID:-}
|
||||
PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET=${PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET:-}
|
||||
PLUGIN_ALIYUN_OSS_AUTH_VERSION=${PLUGIN_ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||
PLUGIN_ALIYUN_OSS_ENDPOINT=${PLUGIN_ALIYUN_OSS_ENDPOINT:-}
|
||||
PLUGIN_ALIYUN_OSS_PATH=${PLUGIN_ALIYUN_OSS_PATH:-}
|
||||
PLUGIN_ALIYUN_OSS_REGION=${PLUGIN_ALIYUN_OSS_REGION:-}
|
||||
PLUGIN_AWS_ACCESS_KEY=${PLUGIN_AWS_ACCESS_KEY:-}
|
||||
PLUGIN_AWS_REGION=${PLUGIN_AWS_REGION:-}
|
||||
PLUGIN_AWS_SECRET_KEY=${PLUGIN_AWS_SECRET_KEY:-}
|
||||
PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING=${PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING:-}
|
||||
PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME=${PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME:-}
|
||||
DB_SSL_MODE=${DB_SSL_MODE:-disable}
|
||||
PLUGIN_MAX_PACKAGE_SIZE=${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PIP_MIRROR_URL=${PIP_MIRROR_URL:-}
|
||||
PLUGIN_INSTALLED_PATH=${PLUGIN_INSTALLED_PATH:-plugin}
|
||||
PLUGIN_MEDIA_CACHE_PATH=${PLUGIN_MEDIA_CACHE_PATH:-assets}
|
||||
PLUGIN_PACKAGE_CACHE_PATH=${PLUGIN_PACKAGE_CACHE_PATH:-plugin_packages}
|
||||
PLUGIN_S3_ENDPOINT=${PLUGIN_S3_ENDPOINT:-}
|
||||
PLUGIN_S3_USE_AWS=${PLUGIN_S3_USE_AWS:-false}
|
||||
PLUGIN_S3_USE_AWS_MANAGED_IAM=${PLUGIN_S3_USE_AWS_MANAGED_IAM:-false}
|
||||
PLUGIN_S3_USE_PATH_STYLE=${PLUGIN_S3_USE_PATH_STYLE:-false}
|
||||
PLUGIN_SENTRY_DSN=${PLUGIN_SENTRY_DSN:-}
|
||||
PLUGIN_SENTRY_ENABLED=${PLUGIN_SENTRY_ENABLED:-false}
|
||||
PLUGIN_TENCENT_COS_REGION=${PLUGIN_TENCENT_COS_REGION:-}
|
||||
PLUGIN_TENCENT_COS_SECRET_ID=${PLUGIN_TENCENT_COS_SECRET_ID:-}
|
||||
PLUGIN_TENCENT_COS_SECRET_KEY=${PLUGIN_TENCENT_COS_SECRET_KEY:-}
|
||||
PLUGIN_VOLCENGINE_TOS_ACCESS_KEY=${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||
PLUGIN_VOLCENGINE_TOS_ENDPOINT=${PLUGIN_VOLCENGINE_TOS_ENDPOINT:-}
|
||||
PLUGIN_VOLCENGINE_TOS_REGION=${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||
PLUGIN_VOLCENGINE_TOS_SECRET_KEY=${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
ALIYUN_OSS_ACCESS_KEY_ID=${PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID:-}
|
||||
ALIYUN_OSS_ACCESS_KEY_SECRET=${PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET:-}
|
||||
ALIYUN_OSS_AUTH_VERSION=${PLUGIN_ALIYUN_OSS_AUTH_VERSION:-v4}
|
||||
ALIYUN_OSS_ENDPOINT=${PLUGIN_ALIYUN_OSS_ENDPOINT:-}
|
||||
ALIYUN_OSS_PATH=${PLUGIN_ALIYUN_OSS_PATH:-}
|
||||
ALIYUN_OSS_REGION=${PLUGIN_ALIYUN_OSS_REGION:-}
|
||||
AWS_ACCESS_KEY=${PLUGIN_AWS_ACCESS_KEY:-}
|
||||
AWS_REGION=${PLUGIN_AWS_REGION:-}
|
||||
AWS_SECRET_KEY=${PLUGIN_AWS_SECRET_KEY:-}
|
||||
AZURE_BLOB_STORAGE_CONNECTION_STRING=${PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING:-}
|
||||
AZURE_BLOB_STORAGE_CONTAINER_NAME=${PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME:-}
|
||||
DB_DATABASE=${DB_PLUGIN_DATABASE:-dify_plugin}
|
||||
DIFY_INNER_API_KEY=${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
DIFY_INNER_API_URL=${PLUGIN_DIFY_INNER_API_URL:-http://api:5001}
|
||||
MAX_PLUGIN_PACKAGE_SIZE=${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
PLUGIN_REMOTE_INSTALLING_HOST=${PLUGIN_DEBUGGING_HOST:-0.0.0.0}
|
||||
PPROF_ENABLED=${PLUGIN_PPROF_ENABLED:-false}
|
||||
PYTHON_ENV_INIT_TIMEOUT=${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120}
|
||||
S3_ENDPOINT=${PLUGIN_S3_ENDPOINT:-}
|
||||
S3_USE_AWS=${PLUGIN_S3_USE_AWS:-false}
|
||||
S3_USE_AWS_MANAGED_IAM=${PLUGIN_S3_USE_AWS_MANAGED_IAM:-false}
|
||||
S3_USE_PATH_STYLE=${PLUGIN_S3_USE_PATH_STYLE:-false}
|
||||
SENTRY_DSN=${PLUGIN_SENTRY_DSN:-}
|
||||
SENTRY_ENABLED=${PLUGIN_SENTRY_ENABLED:-false}
|
||||
SERVER_KEY=${PLUGIN_DAEMON_KEY:-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}
|
||||
SERVER_PORT=${PLUGIN_DAEMON_PORT:-5002}
|
||||
TENCENT_COS_REGION=${PLUGIN_TENCENT_COS_REGION:-}
|
||||
TENCENT_COS_SECRET_ID=${PLUGIN_TENCENT_COS_SECRET_ID:-}
|
||||
TENCENT_COS_SECRET_KEY=${PLUGIN_TENCENT_COS_SECRET_KEY:-}
|
||||
VOLCENGINE_TOS_ACCESS_KEY=${PLUGIN_VOLCENGINE_TOS_ACCESS_KEY:-}
|
||||
VOLCENGINE_TOS_ENDPOINT=${PLUGIN_VOLCENGINE_TOS_ENDPOINT:-}
|
||||
VOLCENGINE_TOS_REGION=${PLUGIN_VOLCENGINE_TOS_REGION:-}
|
||||
VOLCENGINE_TOS_SECRET_KEY=${PLUGIN_VOLCENGINE_TOS_SECRET_KEY:-}
|
||||
@@ -1,25 +0,0 @@
|
||||
# ------------------------------
|
||||
# Plugin Daemon Configuration
|
||||
# ------------------------------
|
||||
|
||||
DB_PLUGIN_DATABASE=dify_plugin
|
||||
PLUGIN_DAEMON_URL=http://plugin_daemon:5002
|
||||
PLUGIN_PPROF_ENABLED=false
|
||||
PLUGIN_DIFY_INNER_API_URL=http://api:5001
|
||||
FORCE_VERIFYING_SIGNATURE=true
|
||||
PLUGIN_STDIO_BUFFER_SIZE=1024
|
||||
PLUGIN_STDIO_MAX_BUFFER_SIZE=5242880
|
||||
PLUGIN_PYTHON_ENV_INIT_TIMEOUT=120
|
||||
PLUGIN_MAX_EXECUTION_TIMEOUT=600
|
||||
PLUGIN_DEBUGGING_HOST=0.0.0.0
|
||||
PLUGIN_DEBUGGING_PORT=5003
|
||||
PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
|
||||
PLUGIN_DIFY_INNER_API_KEY=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
|
||||
PLUGIN_DAEMON_PORT=5002
|
||||
CELERY_WORKER_CLASS=
|
||||
PLUGIN_STORAGE_TYPE=local
|
||||
PLUGIN_STORAGE_LOCAL_ROOT=/app/storage
|
||||
PLUGIN_WORKING_PATH=/app/storage/cwd
|
||||
# Optional: set in docker/.env for Docker/WSL bind-mount permission errors (langgenius/dify#42433).
|
||||
# UV_CACHE_DIR=/tmp/.uv-cache
|
||||
PLUGIN_STORAGE_OSS_BUCKET=
|
||||
@@ -0,0 +1,26 @@
|
||||
# Defaults for sandbox. Copy this file to sandbox.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
SANDBOX_HTTP_PROXY=${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}
|
||||
SANDBOX_HTTPS_PROXY=${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
|
||||
SANDBOX_PORT=${SANDBOX_PORT:-8194}
|
||||
PIP_MIRROR_URL=${PIP_MIRROR_URL:-}
|
||||
# Use a strong key for your deployment, generated with `openssl rand -base64 42`.
|
||||
# Set the same value for CODE_EXECUTION_API_KEY in the API/worker configuration.
|
||||
SANDBOX_API_KEY=${SANDBOX_API_KEY:-dify-sandbox}
|
||||
SANDBOX_GIN_MODE=${SANDBOX_GIN_MODE:-release}
|
||||
SANDBOX_WORKER_TIMEOUT=${SANDBOX_WORKER_TIMEOUT:-15}
|
||||
# Dify's code executor requests networking; false rejects those requests.
|
||||
# Sandbox 0.2.15 on ARM64 can also fail with "operation not permitted" for
|
||||
# requests with enable_network=false, even without network operations:
|
||||
# the runtime needs epoll_pwait, which is only allowed with networking enabled.
|
||||
SANDBOX_ENABLE_NETWORK=${SANDBOX_ENABLE_NETWORK:-true}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
API_KEY=${SANDBOX_API_KEY:-dify-sandbox}
|
||||
ENABLE_NETWORK=${SANDBOX_ENABLE_NETWORK:-true}
|
||||
GIN_MODE=${SANDBOX_GIN_MODE:-release}
|
||||
HTTPS_PROXY=${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
|
||||
HTTP_PROXY=${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}
|
||||
WORKER_TIMEOUT=${SANDBOX_WORKER_TIMEOUT:-15}
|
||||
@@ -1,17 +0,0 @@
|
||||
# ------------------------------
|
||||
# Sandbox Configuration
|
||||
# ------------------------------
|
||||
|
||||
SANDBOX_HTTP_PROXY=http://ssrf_proxy:3128
|
||||
SANDBOX_HTTPS_PROXY=http://ssrf_proxy:3128
|
||||
SANDBOX_PORT=8194
|
||||
PIP_MIRROR_URL=
|
||||
SANDBOX_API_KEY=dify-sandbox
|
||||
SANDBOX_GIN_MODE=release
|
||||
SANDBOX_WORKER_TIMEOUT=15
|
||||
SANDBOX_ENABLE_NETWORK=true
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_GRACEFUL_PERIOD=21
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE=1000
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL=200
|
||||
SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS=30
|
||||
SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL=90000
|
||||
@@ -1,28 +1,567 @@
|
||||
# Docker-specific defaults, loaded before optional env files and docker/.env.
|
||||
# Keep runtime defaults in the application or Compose; only Docker overrides belong here.
|
||||
# Override these values in docker/.env or the matching envs/*.env file, not here.
|
||||
CONSOLE_CORS_ALLOW_ORIGINS=*
|
||||
TRIGGER_URL=http://localhost
|
||||
ENDPOINT_URL_TEMPLATE=http://localhost/e/{hook_id}
|
||||
MIGRATION_ENABLED=true
|
||||
LOG_FILE=/app/logs/server.log
|
||||
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
|
||||
CELERY_WORKER_AMOUNT=4
|
||||
DB_HOST=db_postgres
|
||||
DB_PASSWORD=difyai123456
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=difyai123456
|
||||
REDIS_KEEPALIVE=true
|
||||
CELERY_BROKER_URL=redis://:${REDIS_PASSWORD:-difyai123456}@${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/1
|
||||
OPENDAL_FS_ROOT=storage
|
||||
VECTOR_STORE=weaviate
|
||||
WEAVIATE_ENDPOINT=http://weaviate:8080
|
||||
WEAVIATE_API_KEY=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_GRPC_ENDPOINT=grpc://weaviate:50051
|
||||
SSRF_PROXY_HTTP_URL=http://ssrf_proxy:3128
|
||||
SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128
|
||||
PLUGIN_DAEMON_URL=http://plugin_daemon:5002
|
||||
PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
|
||||
PLUGIN_MAX_PACKAGE_SIZE=52428800
|
||||
AGENT_BACKEND_BASE_URL=http://agent_backend:5050
|
||||
NEXT_PUBLIC_ENABLE_AGENT_V2=true
|
||||
# Shared API, worker and Beat configuration. Copy this file to shared.env to customize it.
|
||||
# Edit the copy; docker/.env takes precedence. Existing shared.env files remain supported.
|
||||
# Active assignments preserve Docker defaults and explicit overrides, including empty values.
|
||||
# Optional application/provider settings are commented examples: uncomment only what you need.
|
||||
# Do not uncomment empty values or placeholders unless you intend to set them.
|
||||
# Remove accidental empty overrides (especially CELERY_WORKER_AMOUNT=) to restore defaults.
|
||||
# API process settings: api.defaults. Worker process settings: worker.defaults.
|
||||
# Sentry mappings: api.defaults and worker.defaults. Web and plugin-daemon settings stay in their files.
|
||||
# Shared secrets and token lifetimes: copy ../security.env.example to ../security.env.
|
||||
# Set COMPOSE_PROFILES in docker/.env; Compose reads it before service env files.
|
||||
# Set EXPOSE_NGINX_PORT in docker/.env; Compose reads published ports before service env files.
|
||||
# Set EXPOSE_NGINX_SSL_PORT in docker/.env; Compose reads published ports before service env files.
|
||||
# Set EXPOSE_PLUGIN_DEBUGGING_HOST in docker/.env; the API and daemon must use the published address.
|
||||
# Set EXPOSE_PLUGIN_DEBUGGING_PORT in docker/.env; the API and daemon must use the published port.
|
||||
|
||||
# ------------------------------
|
||||
# URLs, deployment and locale
|
||||
# ------------------------------
|
||||
# CONSOLE_WEB_URL=
|
||||
# SERVICE_API_URL=
|
||||
TRIGGER_URL=${TRIGGER_URL-http://localhost}
|
||||
# APP_WEB_URL=
|
||||
# FILES_URL=
|
||||
# INTERNAL_FILES_URL=
|
||||
ENDPOINT_URL_TEMPLATE=${ENDPOINT_URL_TEMPLATE-http://localhost/e/{hook_id}}
|
||||
# DEPLOY_ENV=PRODUCTION
|
||||
# DEPLOYMENT_EDITION=COMMUNITY
|
||||
MIGRATION_ENABLED=${MIGRATION_ENABLED-true}
|
||||
# LANG=C.UTF-8
|
||||
# LC_ALL=C.UTF-8
|
||||
# PYTHONIOENCODING=utf-8
|
||||
# CHECK_UPDATE_URL=https://updates.dify.ai
|
||||
# OPENAI_API_BASE=https://api.openai.com/v1
|
||||
# Nacos remote settings source HTTP timeouts (seconds).
|
||||
# Bound how long requests to the Nacos endpoint wait before failing, so a slow or
|
||||
# unresponsive Nacos server cannot stall API startup or token refresh.
|
||||
# DIFY_ENV_NACOS_REQUEST_TIMEOUT=10.0
|
||||
# DIFY_ENV_NACOS_CONNECT_TIMEOUT=3.0
|
||||
|
||||
# ------------------------------
|
||||
# System features and account access
|
||||
# ------------------------------
|
||||
# MARKETPLACE_ENABLED=true
|
||||
# ENABLE_EMAIL_CODE_LOGIN=false
|
||||
# EMAIL_CODE_LOGIN_TOKEN_EXPIRY_MINUTES=5
|
||||
# EMAIL_CODE_LOGIN_MAX_ATTEMPTS=5
|
||||
# ENABLE_EMAIL_PASSWORD_LOGIN=true
|
||||
# ENABLE_SOCIAL_OAUTH_LOGIN=false
|
||||
# Remove `collaboration` from COMPOSE_PROFILES to stop the dedicated websocket service.
|
||||
# ENABLE_COLLABORATION_MODE=true
|
||||
# ALLOW_REGISTER=false
|
||||
# ALLOW_CREATE_WORKSPACE=false
|
||||
# ENABLE_CHANGE_EMAIL=true
|
||||
# ENABLE_TRIAL_APP=false
|
||||
# ENABLE_EXPLORE_BANNER=false
|
||||
# ENABLE_LEARN_APP=true
|
||||
# ENABLE_STEP_BY_STEP_TOUR=false
|
||||
# ENABLE_SKILL=true
|
||||
# RBAC_ENABLED=false
|
||||
# ENABLE_LICENSE_EXPIRY_NOTICE=true
|
||||
# ACCESS_TOKEN_EXPIRE_MINUTES=60
|
||||
# REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||
# INVITE_EXPIRY_HOURS=72
|
||||
# WEB_API_CORS_ALLOW_ORIGINS=*
|
||||
CONSOLE_CORS_ALLOW_ORIGINS=${CONSOLE_CORS_ALLOW_ORIGINS-*}
|
||||
# COOKIE_DOMAIN=
|
||||
|
||||
# ------------------------------
|
||||
# API and Celery Docker defaults
|
||||
# ------------------------------
|
||||
# Unset values use these Docker defaults; an explicit empty value remains an override.
|
||||
SERVER_WORKER_CLASS=${SERVER_WORKER_CLASS-gevent}
|
||||
GUNICORN_TIMEOUT=${GUNICORN_TIMEOUT-360}
|
||||
CELERY_WORKER_AMOUNT=${CELERY_WORKER_AMOUNT-4}
|
||||
|
||||
# ------------------------------
|
||||
# Celery broker and KnowledgeFS dispatch
|
||||
# ------------------------------
|
||||
# Broker URL defaults/mappings live in api.defaults, worker.defaults and worker-beat.defaults.
|
||||
# Set a common CELERY_BROKER_URL override in shared.env or docker/.env for every producer/consumer.
|
||||
# Optional long-running KnowledgeFS Celery rollout: set identically in every API, worker and Beat
|
||||
# process sharing this Redis broker. It must exceed the KnowledgeFS hard task limit (7230s by
|
||||
# default). Keep unset to preserve Celery's existing default when this rollout is disabled.
|
||||
# CELERY_BROKER_VISIBILITY_TIMEOUT=10800
|
||||
# CELERY_TASK_ANNOTATIONS=null
|
||||
# CELERY_SENTINEL_PASSWORD=
|
||||
# CELERY_BACKEND=redis
|
||||
# CELERY_USE_SENTINEL=false
|
||||
# CELERY_SENTINEL_MASTER_NAME=
|
||||
# CELERY_SENTINEL_SOCKET_TIMEOUT=0.1
|
||||
# KNOWLEDGE_FS_BACKGROUND_WORKER_ENABLED=true
|
||||
# KNOWLEDGE_FS_BACKGROUND_POLL_INTERVAL_SECONDS=5
|
||||
|
||||
# ------------------------------
|
||||
# Database and Redis connections
|
||||
# ------------------------------
|
||||
DB_HOST=${DB_HOST-db_postgres}
|
||||
DB_USERNAME=${DB_USERNAME-postgres}
|
||||
DB_PASSWORD=${DB_PASSWORD-difyai123456}
|
||||
DB_PORT=${DB_PORT-5432}
|
||||
REDIS_HOST=${REDIS_HOST-redis}
|
||||
REDIS_PASSWORD=${REDIS_PASSWORD-difyai123456}
|
||||
REDIS_PORT=${REDIS_PORT-6379}
|
||||
REDIS_KEEPALIVE=${REDIS_KEEPALIVE-true}
|
||||
|
||||
# ------------------------------
|
||||
# Logging, traces and telemetry
|
||||
# ------------------------------
|
||||
# LOG_LEVEL=INFO
|
||||
# LOG_OUTPUT_FORMAT=text
|
||||
LOG_FILE=${LOG_FILE-/app/logs/server.log}
|
||||
# LOG_FILE_MAX_SIZE=20
|
||||
# LOG_FILE_BACKUP_COUNT=5
|
||||
LOG_DATEFORMAT=${LOG_DATEFORMAT-%Y-%m-%d %H:%M:%S}
|
||||
# LOG_TZ=UTC
|
||||
# DEBUG=false
|
||||
# FLASK_DEBUG=false
|
||||
# ENABLE_REQUEST_LOGGING=False
|
||||
# Application-level Agent tracing; also enable the collector in dify-agent.env.
|
||||
# OPS_AGENT_TRACE_ENABLED=false
|
||||
# ENABLE_APPLICATION_TRACE_RECONCILE_TASK=true
|
||||
# Shared by API, workers, and Beat. Keep separate from legacy ops_trace during upgrades.
|
||||
# OPS_TRACE_QUEUE=ops_trace_v2
|
||||
# Attempts to send one trace while its provider is temporarily unavailable.
|
||||
# OPS_TRACE_EXPORT_MAX_ATTEMPTS=6
|
||||
# Daily cleanup of trace payloads an interrupted delivery left in storage.
|
||||
# ENABLE_TRACE_PAYLOAD_SWEEP_TASK=true
|
||||
# ENABLE_OTEL=false
|
||||
# OTLP_TRACE_ENDPOINT=
|
||||
# OTLP_METRIC_ENDPOINT=
|
||||
# OTLP_BASE_ENDPOINT=http://localhost:4318
|
||||
# OTEL_EXPORTER_OTLP_PROTOCOL=
|
||||
# OTEL_EXPORTER_TYPE=otlp
|
||||
# OTEL_SAMPLING_RATE=0.1
|
||||
# OTEL_BATCH_EXPORT_SCHEDULE_DELAY=5000
|
||||
# OTEL_MAX_QUEUE_SIZE=2048
|
||||
# OTEL_MAX_EXPORT_BATCH_SIZE=512
|
||||
# OTEL_METRIC_EXPORT_INTERVAL=60000
|
||||
# OTEL_BATCH_EXPORT_TIMEOUT=10000
|
||||
# OTEL_METRIC_EXPORT_TIMEOUT=30000
|
||||
|
||||
# ------------------------------
|
||||
# Uploads, parsing and package limits
|
||||
# ------------------------------
|
||||
# These parser settings are for Dify; knowledge-fs.env configures the separate KnowledgeFS parser client.
|
||||
# FILES_ACCESS_TIMEOUT=300
|
||||
# UPLOAD_FILE_SIZE_LIMIT=15
|
||||
# KNOWLEDGE_UPLOAD_FILE_SIZE_LIMIT_FOR_PAID_PLAN=15
|
||||
# UPLOAD_FILE_BATCH_LIMIT=5
|
||||
# UPLOAD_FILE_EXTENSION_BLACKLIST=
|
||||
# SINGLE_CHUNK_ATTACHMENT_LIMIT=10
|
||||
# IMAGE_FILE_BATCH_LIMIT=10
|
||||
# ATTACHMENT_IMAGE_FILE_SIZE_LIMIT=2
|
||||
# ATTACHMENT_IMAGE_DOWNLOAD_TIMEOUT=60
|
||||
# ETL_TYPE=dify
|
||||
# UNSTRUCTURED_API_URL=
|
||||
# MULTIMODAL_SEND_FORMAT=base64
|
||||
# UPLOAD_IMAGE_FILE_SIZE_LIMIT=10
|
||||
# UPLOAD_VIDEO_FILE_SIZE_LIMIT=100
|
||||
# UPLOAD_AUDIO_FILE_SIZE_LIMIT=50
|
||||
# UPLOAD_SKILL_FILE_SIZE_LIMIT=50
|
||||
# SKILL_PACKAGE_MAX_UNCOMPRESSED_BYTES=209715200
|
||||
# SKILL_PACKAGE_MAX_ENTRIES=5000
|
||||
# SKILL_PACKAGE_MAX_SKILL_MD_BYTES=1048576
|
||||
# AGENT_PACKAGE_MAX_BYTES=536870912
|
||||
# AGENT_PACKAGE_MAX_MANIFEST_BYTES=5242880
|
||||
# AGENT_PACKAGE_MAX_ENTRIES=5000
|
||||
# APP_PACKAGE_MAX_WORKFLOW_TOOLS=20
|
||||
# SCARF_NO_ANALYTICS=true
|
||||
# ANNOTATION_IMPORT_FILE_SIZE_LIMIT=2
|
||||
# ANNOTATION_IMPORT_MAX_RECORDS=10000
|
||||
# ANNOTATION_IMPORT_MIN_RECORDS=1
|
||||
# ANNOTATION_IMPORT_RATE_LIMIT_PER_MINUTE=5
|
||||
# ANNOTATION_IMPORT_RATE_LIMIT_PER_HOUR=20
|
||||
# ANNOTATION_IMPORT_MAX_CONCURRENT=5
|
||||
|
||||
# ------------------------------
|
||||
# Plugin clients and marketplace
|
||||
# ------------------------------
|
||||
# Set PLUGIN_DAEMON_KEY in docker/.env; the daemon, API, workers, and Agent must use the same key.
|
||||
# Set PLUGIN_DIFY_INNER_API_KEY in docker/.env; the API, daemon, workers, Agent and KnowledgeFS share it.
|
||||
# Keep the PLUGIN_DAEMON_KEY expression below unchanged in the copy.
|
||||
PLUGIN_DAEMON_URL=${PLUGIN_DAEMON_URL-http://plugin_daemon:5002}
|
||||
PLUGIN_DAEMON_KEY=${PLUGIN_DAEMON_KEY-lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi}
|
||||
PLUGIN_MAX_PACKAGE_SIZE=${PLUGIN_MAX_PACKAGE_SIZE-52428800}
|
||||
# PLUGIN_MAX_FILE_SIZE=52428800
|
||||
# PLUGIN_MODEL_SCHEMA_CACHE_TTL=3600
|
||||
# PLUGIN_MODEL_PROVIDERS_CACHE_ENABLED=true
|
||||
# PLUGIN_MODEL_PROVIDERS_CACHE_TTL=86400
|
||||
# Comma-separated marketplace plugin IDs whose latest versions are installed for newly registered users.
|
||||
# Example: langgenius/openai,langgenius/gemini
|
||||
# NEW_USER_DEFAULT_PLUGIN_IDS=
|
||||
# Comma-separated model_type:provider:model entries assigned after default plugins finish installing.
|
||||
# Example: llm:langgenius/openai/openai:gpt-4o-mini,text-embedding:langgenius/openai/openai:text-embedding-3-small
|
||||
# NEW_USER_DEFAULT_MODELS=
|
||||
# POSITION_TOOL_PINS=
|
||||
# POSITION_TOOL_INCLUDES=
|
||||
# POSITION_TOOL_EXCLUDES=
|
||||
# POSITION_PROVIDER_PINS=
|
||||
# POSITION_PROVIDER_INCLUDES=
|
||||
# POSITION_PROVIDER_EXCLUDES=
|
||||
# CREATORS_PLATFORM_FEATURES_ENABLED=true
|
||||
# CREATORS_PLATFORM_API_URL=https://creators.dify.ai
|
||||
# CREATORS_PLATFORM_OAUTH_CLIENT_ID=
|
||||
|
||||
# ------------------------------
|
||||
# Agent clients and execution
|
||||
# ------------------------------
|
||||
AGENT_BACKEND_BASE_URL=${AGENT_BACKEND_BASE_URL-http://agent_backend:5050}
|
||||
NEXT_PUBLIC_ENABLE_AGENT_V2=${NEXT_PUBLIC_ENABLE_AGENT_V2-true}
|
||||
# Agent backend client settings shared by API and worker processes.
|
||||
# AGENT_BACKEND_STREAM_READ_TIMEOUT_SECONDS=30
|
||||
# AGENT_BACKEND_STREAM_MAX_RECONNECTS=3
|
||||
# Client timeout for Agent backend calls that may carry a Home Snapshot transfer.
|
||||
# Must stay above DIFY_AGENT_ENTERPRISE_SANDBOX_SNAPSHOT_TIMEOUT on the Agent backend.
|
||||
# AGENT_BACKEND_HOME_SNAPSHOT_TIMEOUT_SECONDS=45
|
||||
# Independent E2B accounting, collected only by API Celery Beat/workers.
|
||||
# Uses OPS_TRACE_QUEUE; business binding operations never call metering.
|
||||
# Enable after migrations. START_AT is an immutable, whole-second UTC T0.
|
||||
# AGENT_SANDBOX_METERING_ENABLED=false
|
||||
# AGENT_SANDBOX_METERING_PROJECT_ID=
|
||||
# AGENT_SANDBOX_METERING_START_AT=
|
||||
# AGENT_SANDBOX_METERING_INTERVAL_SECONDS=60
|
||||
# APP_DEFAULT_ACTIVE_REQUESTS=0
|
||||
# APP_MAX_ACTIVE_REQUESTS=0
|
||||
# Outer execution limit for Agent Apps. Agent Backend may stop the internal
|
||||
# model/tool loop sooner when DIFY_AGENT_RUN_TIMEOUT_SECONDS is lower.
|
||||
# APP_MAX_EXECUTION_TIME=3600
|
||||
|
||||
# ------------------------------
|
||||
# Code execution and template transformation
|
||||
# ------------------------------
|
||||
# CODE_EXECUTION_ENDPOINT=http://sandbox:8194
|
||||
# CODE_EXECUTION_SSL_VERIFY=True
|
||||
# CODE_EXECUTION_POOL_MAX_CONNECTIONS=100
|
||||
# CODE_EXECUTION_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
# CODE_EXECUTION_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
# CODE_MAX_NUMBER=9223372036854775807
|
||||
# CODE_MIN_NUMBER=-9223372036854775808
|
||||
# CODE_MAX_DEPTH=5
|
||||
# CODE_MAX_PRECISION=20
|
||||
# CODE_MAX_STRING_LENGTH=400000
|
||||
# CODE_MAX_STRING_ARRAY_LENGTH=30
|
||||
# CODE_MAX_OBJECT_ARRAY_LENGTH=30
|
||||
# CODE_MAX_NUMBER_ARRAY_LENGTH=1000
|
||||
# CODE_EXECUTION_CONNECT_TIMEOUT=10
|
||||
# CODE_EXECUTION_READ_TIMEOUT=60
|
||||
# CODE_EXECUTION_WRITE_TIMEOUT=10
|
||||
# TEMPLATE_TRANSFORM_MAX_LENGTH=400000
|
||||
|
||||
# ------------------------------
|
||||
# Workflow and HTTP request limits
|
||||
# ------------------------------
|
||||
# WORKFLOW_MAX_EXECUTION_STEPS=500
|
||||
# Outer execution limit for Workflow and Chatflow callers. Agent Backend may
|
||||
# stop the internal model/tool loop sooner when its run timeout is lower.
|
||||
# To allow all Agent call paths to run for one hour, set this value,
|
||||
# APP_MAX_EXECUTION_TIME, and DIFY_AGENT_RUN_TIMEOUT_SECONDS to at least 3600.
|
||||
# WORKFLOW_MAX_EXECUTION_TIME=3600
|
||||
# WORKFLOW_CALL_MAX_DEPTH=5
|
||||
# MAX_VARIABLE_SIZE=204800
|
||||
# WORKFLOW_GENERATOR_NODE_BUILDER_MAX_WORKERS=6
|
||||
# WORKFLOW_FILE_UPLOAD_LIMIT=10
|
||||
# GRAPH_ENGINE_MAX_WORKERS=10
|
||||
# API_TOOL_DEFAULT_CONNECT_TIMEOUT=10
|
||||
# API_TOOL_DEFAULT_READ_TIMEOUT=60
|
||||
# WEBHOOK_REQUEST_BODY_MAX_SIZE=10485760
|
||||
# HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
|
||||
# HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
|
||||
# HTTP_REQUEST_NODE_SSL_VERIFY=True
|
||||
# HTTP_REQUEST_MAX_CONNECT_TIMEOUT=10
|
||||
# HTTP_REQUEST_MAX_READ_TIMEOUT=600
|
||||
# HTTP_REQUEST_MAX_WRITE_TIMEOUT=600
|
||||
# DSL_EXPORT_ENCRYPT_DATASET_ID=true
|
||||
# DATASET_MAX_SEGMENTS_PER_REQUEST=0
|
||||
|
||||
# ------------------------------
|
||||
# Workflow storage and retention
|
||||
# ------------------------------
|
||||
# WORKFLOW_NODE_EXECUTION_STORAGE=rdbms
|
||||
# CORE_WORKFLOW_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_execution_repository.SQLAlchemyWorkflowExecutionRepository
|
||||
# CORE_WORKFLOW_NODE_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_node_execution_repository.SQLAlchemyWorkflowNodeExecutionRepository
|
||||
# API_WORKFLOW_RUN_REPOSITORY=repositories.sqlalchemy_api_workflow_run_repository.DifyAPISQLAlchemyWorkflowRunRepository
|
||||
# API_WORKFLOW_NODE_EXECUTION_REPOSITORY=repositories.sqlalchemy_api_workflow_node_execution_repository.DifyAPISQLAlchemyWorkflowNodeExecutionRepository
|
||||
# WORKFLOW_LOG_CLEANUP_ENABLED=false
|
||||
# WORKFLOW_LOG_RETENTION_DAYS=30
|
||||
# WORKFLOW_LOG_CLEANUP_BATCH_SIZE=100
|
||||
# WORKFLOW_LOG_CLEANUP_SPECIFIC_WORKFLOW_IDS=
|
||||
# ALIYUN_SLS_ENDPOINT=
|
||||
# ALIYUN_SLS_REGION=
|
||||
# ALIYUN_SLS_PROJECT_NAME=
|
||||
# ALIYUN_SLS_LOGSTORE_TTL=365
|
||||
# LOGSTORE_DUAL_WRITE_ENABLED=false
|
||||
# LOGSTORE_DUAL_READ_ENABLED=true
|
||||
# LOGSTORE_ENABLE_PUT_GRAPH_FIELD=true
|
||||
|
||||
# ------------------------------
|
||||
# Scheduled tasks and queue monitoring (API, workers and Beat)
|
||||
# ------------------------------
|
||||
# ENABLE_CLEAN_EMBEDDING_CACHE_TASK=false
|
||||
# ENABLE_CLEAN_UNUSED_DATASETS_TASK=false
|
||||
# ENABLE_CREATE_TIDB_SERVERLESS_TASK=false
|
||||
# ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK=false
|
||||
# ENABLE_CLEAN_MESSAGES=false
|
||||
# ENABLE_WORKFLOW_RUN_CLEANUP_TASK=false
|
||||
# ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK=false
|
||||
# ENABLE_DATASETS_QUEUE_MONITOR=false
|
||||
# ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK=true
|
||||
# ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK=true
|
||||
# WORKFLOW_SCHEDULE_POLLER_INTERVAL=1
|
||||
# WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE=100
|
||||
# WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK=0
|
||||
# TENANT_ISOLATED_TASK_CONCURRENCY=1
|
||||
# QUEUE_MONITOR_THRESHOLD=200
|
||||
# QUEUE_MONITOR_ALERT_EMAILS=
|
||||
# QUEUE_MONITOR_INTERVAL=30
|
||||
# HUMAN_INPUT_IM_EVENT_TRANSPORT_MODE=WEBHOOK
|
||||
# ENABLE_HUMAN_INPUT_TIMEOUT_TASK=true
|
||||
# HUMAN_INPUT_TIMEOUT_TASK_INTERVAL=1
|
||||
# ENABLE_CONVERSATION_CLEANUP_TASK=true
|
||||
# CONVERSATION_CLEANUP_TASK_INTERVAL=5
|
||||
# CONVERSATION_CLEANUP_BATCH_SIZE=100
|
||||
# Expired sandbox records are cleaned by API/Celery, not the sandbox container.
|
||||
# SANDBOX_EXPIRED_RECORDS_CLEAN_GRACEFUL_PERIOD=21
|
||||
# SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE=1000
|
||||
# SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL=200
|
||||
# SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS=30
|
||||
# SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL=90000
|
||||
# CREATE_TIDB_SERVICE_JOB_ENABLED=false
|
||||
# MAX_SUBMIT_COUNT=100
|
||||
|
||||
# ------------------------------
|
||||
# Email and Notion integrations
|
||||
# ------------------------------
|
||||
# NOTION_INTEGRATION_TYPE=public
|
||||
# NOTION_CLIENT_ID=
|
||||
# MAIL_TYPE=resend
|
||||
# MAIL_DEFAULT_SEND_FROM=
|
||||
# RESEND_API_URL=https://api.resend.com
|
||||
# SMTP_SERVER=
|
||||
# SMTP_PORT=465
|
||||
# SMTP_USERNAME=
|
||||
# SMTP_USE_TLS=true
|
||||
# SMTP_OPPORTUNISTIC_TLS=false
|
||||
# SMTP_LOCAL_HOSTNAME=
|
||||
|
||||
# ------------------------------
|
||||
# SSRF proxy clients
|
||||
# ------------------------------
|
||||
# Client timeouts/pool limits and Squid settings: ../infrastructure/ssrf-proxy.defaults.
|
||||
SSRF_PROXY_HTTP_URL=${SSRF_PROXY_HTTP_URL-http://ssrf_proxy:3128}
|
||||
SSRF_PROXY_HTTPS_URL=${SSRF_PROXY_HTTPS_URL-http://ssrf_proxy:3128}
|
||||
|
||||
# ------------------------------
|
||||
# Storage and encryption providers
|
||||
# ------------------------------
|
||||
# Application storage settings below also serve workers; plugin-daemon.defaults configures plugin storage separately.
|
||||
# STORAGE_TYPE=opendal
|
||||
# KEY_PROVIDER_TYPE=local
|
||||
# OPENDAL_SCHEME=fs
|
||||
OPENDAL_FS_ROOT=${OPENDAL_FS_ROOT-storage}
|
||||
# AZURE_KEYVAULT_VAULT_URL=
|
||||
# AZURE_KEYVAULT_KEY_SIZE=2048
|
||||
# AZURE_KEYVAULT_ROTATION_INTERVAL_DAYS=
|
||||
|
||||
# ------------------------------
|
||||
# Amazon S3 and archive storage
|
||||
# ------------------------------
|
||||
# S3_ENDPOINT=
|
||||
# S3_REGION=us-east-1
|
||||
# S3_BUCKET_NAME=difyai
|
||||
# S3_ACCESS_KEY=
|
||||
# S3_SECRET_KEY=
|
||||
# S3_ADDRESS_STYLE=auto
|
||||
# S3_USE_AWS_MANAGED_IAM=false
|
||||
# ARCHIVE_STORAGE_ENABLED=false
|
||||
# ARCHIVE_STORAGE_ENDPOINT=
|
||||
# ARCHIVE_STORAGE_ARCHIVE_BUCKET=
|
||||
# ARCHIVE_STORAGE_EXPORT_BUCKET=
|
||||
# ARCHIVE_STORAGE_REGION=auto
|
||||
# ARCHIVE_STORAGE_ACCESS_KEY=
|
||||
# ARCHIVE_STORAGE_SECRET_KEY=
|
||||
# ARCHIVE_STORAGE_ADDRESS_STYLE=path
|
||||
|
||||
# ------------------------------
|
||||
# Azure Blob and Google Cloud Storage
|
||||
# ------------------------------
|
||||
# AZURE_BLOB_ACCOUNT_URL=https://<your_account_name>.blob.core.windows.net
|
||||
# AZURE_BLOB_ACCOUNT_NAME=difyai
|
||||
# AZURE_BLOB_ACCOUNT_KEY=difyai
|
||||
# AZURE_BLOB_CONTAINER_NAME=difyai-container
|
||||
# GOOGLE_STORAGE_BUCKET_NAME=your-bucket-name
|
||||
# GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64=
|
||||
|
||||
# ------------------------------
|
||||
# Aliyun OSS, Tencent COS and Volcengine TOS
|
||||
# ------------------------------
|
||||
# ALIYUN_OSS_BUCKET_NAME=your-bucket-name
|
||||
# ALIYUN_OSS_ENDPOINT=https://oss-ap-southeast-1-internal.aliyuncs.com
|
||||
# ALIYUN_OSS_REGION=ap-southeast-1
|
||||
# ALIYUN_OSS_ACCESS_KEY=your-access-key
|
||||
# ALIYUN_OSS_SECRET_KEY=your-secret-key
|
||||
# ALIYUN_OSS_AUTH_VERSION=v4
|
||||
# ALIYUN_OSS_PATH=your-path
|
||||
# ALIYUN_CLOUDBOX_ID=your-cloudbox-id
|
||||
# TENCENT_COS_BUCKET_NAME=your-bucket-name
|
||||
# TENCENT_COS_REGION=your-region
|
||||
# TENCENT_COS_SECRET_KEY=your-secret-key
|
||||
# TENCENT_COS_SECRET_ID=your-secret-id
|
||||
# TENCENT_COS_SCHEME=your-scheme
|
||||
# TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
|
||||
# VOLCENGINE_TOS_BUCKET_NAME=your-bucket-name
|
||||
# VOLCENGINE_TOS_ENDPOINT=your-server-url
|
||||
# VOLCENGINE_TOS_REGION=your-region
|
||||
# VOLCENGINE_TOS_SECRET_KEY=your-secret-key
|
||||
# VOLCENGINE_TOS_ACCESS_KEY=your-access-key
|
||||
|
||||
# ------------------------------
|
||||
# OCI, Huawei OBS, Baidu OBS and Supabase storage
|
||||
# ------------------------------
|
||||
# OCI_ENDPOINT=https://your-object-storage-namespace.compat.objectstorage.us-ashburn-1.oraclecloud.com
|
||||
# OCI_BUCKET_NAME=your-bucket-name
|
||||
# OCI_REGION=us-ashburn-1
|
||||
# OCI_ACCESS_KEY=your-access-key
|
||||
# OCI_SECRET_KEY=your-secret-key
|
||||
# HUAWEI_OBS_BUCKET_NAME=your-bucket-name
|
||||
# HUAWEI_OBS_SERVER=your-server-url
|
||||
# HUAWEI_OBS_SECRET_KEY=your-secret-key
|
||||
# HUAWEI_OBS_ACCESS_KEY=your-access-key
|
||||
# HUAWEI_OBS_PATH_STYLE=false
|
||||
# BAIDU_OBS_BUCKET_NAME=your-bucket-name
|
||||
# BAIDU_OBS_ENDPOINT=your-server-url
|
||||
# BAIDU_OBS_SECRET_KEY=your-secret-key
|
||||
# BAIDU_OBS_ACCESS_KEY=your-access-key
|
||||
# SUPABASE_URL=your-server-url
|
||||
# SUPABASE_BUCKET_NAME=your-bucket-name
|
||||
# SUPABASE_API_KEY=your-access-key
|
||||
|
||||
# ------------------------------
|
||||
# ClickZetta storage and vector search
|
||||
# ------------------------------
|
||||
# CLICKZETTA_USERNAME=
|
||||
# CLICKZETTA_PASSWORD=
|
||||
# CLICKZETTA_INSTANCE=
|
||||
# CLICKZETTA_SERVICE=api.clickzetta.com
|
||||
# CLICKZETTA_WORKSPACE=quick_start
|
||||
# CLICKZETTA_VCLUSTER=default_ap
|
||||
# CLICKZETTA_SCHEMA=dify
|
||||
# CLICKZETTA_BATCH_SIZE=100
|
||||
# CLICKZETTA_ENABLE_INVERTED_INDEX=true
|
||||
# CLICKZETTA_ANALYZER_TYPE=chinese
|
||||
# CLICKZETTA_ANALYZER_MODE=smart
|
||||
# CLICKZETTA_VECTOR_DISTANCE_FUNCTION=cosine_distance
|
||||
# CLICKZETTA_VOLUME_TYPE=user
|
||||
# CLICKZETTA_VOLUME_NAME=
|
||||
# CLICKZETTA_VOLUME_TABLE_PREFIX=dataset_
|
||||
# CLICKZETTA_VOLUME_DIFY_PREFIX=dify_km
|
||||
|
||||
# ------------------------------
|
||||
# Vector store selection and Docker connection defaults
|
||||
# ------------------------------
|
||||
# Provider client options live in ../vectorstores/{weaviate,qdrant,oceanbase,pgvector}.defaults
|
||||
# and ../vectorstores/milvus.env.example. Their .env overrides reach API, workers and Beat.
|
||||
# KnowledgeFS uses the API vector bridge, not its own vector provider connection.
|
||||
VECTOR_STORE=${VECTOR_STORE-weaviate}
|
||||
# Prefix used to create collection names in the vector database.
|
||||
# VECTOR_INDEX_NAME_PREFIX=Vector_index
|
||||
WEAVIATE_ENDPOINT=${WEAVIATE_ENDPOINT-http://weaviate:8080}
|
||||
WEAVIATE_API_KEY=${WEAVIATE_API_KEY-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
WEAVIATE_GRPC_ENDPOINT=${WEAVIATE_GRPC_ENDPOINT-grpc://weaviate:50051}
|
||||
|
||||
# ------------------------------
|
||||
# TiDB and TiDB on Qdrant
|
||||
# ------------------------------
|
||||
# TIDB_VECTOR_HOST=tidb
|
||||
# TIDB_VECTOR_PORT=4000
|
||||
# TIDB_VECTOR_USER=
|
||||
# TIDB_VECTOR_DATABASE=dify
|
||||
# TIDB_VECTOR_ENABLE_FULLTEXT_SEARCH=false
|
||||
# TIDB_ON_QDRANT_URL=http://127.0.0.1
|
||||
# TIDB_ON_QDRANT_CLIENT_TIMEOUT=20
|
||||
# TIDB_ON_QDRANT_GRPC_ENABLED=false
|
||||
# TIDB_ON_QDRANT_GRPC_PORT=6334
|
||||
# TIDB_ON_QDRANT_ESTIMATED_STORAGE_LIMITS_MB=sandbox:60,professional:6400,team:25600
|
||||
# TIDB_API_URL=http://127.0.0.1
|
||||
# TIDB_IAM_API_URL=http://127.0.0.1
|
||||
# TIDB_REGION=regions/aws-us-east-1
|
||||
# TIDB_PROJECT_ID=dify
|
||||
# TIDB_SPEND_LIMIT=100
|
||||
|
||||
# ------------------------------
|
||||
# Tencent and Baidu vector databases
|
||||
# ------------------------------
|
||||
# TENCENT_VECTOR_DB_URL=http://127.0.0.1
|
||||
# TENCENT_VECTOR_DB_TIMEOUT=30
|
||||
# TENCENT_VECTOR_DB_USERNAME=dify
|
||||
# TENCENT_VECTOR_DB_DATABASE=dify
|
||||
# TENCENT_VECTOR_DB_SHARD=1
|
||||
# TENCENT_VECTOR_DB_REPLICAS=2
|
||||
# TENCENT_VECTOR_DB_ENABLE_HYBRID_SEARCH=false
|
||||
# BAIDU_VECTOR_DB_ENDPOINT=http://127.0.0.1:5287
|
||||
# BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS=30000
|
||||
# BAIDU_VECTOR_DB_ACCOUNT=root
|
||||
# BAIDU_VECTOR_DB_DATABASE=dify
|
||||
# BAIDU_VECTOR_DB_SHARD=1
|
||||
# BAIDU_VECTOR_DB_REPLICAS=3
|
||||
# BAIDU_VECTOR_DB_INVERTED_INDEX_ANALYZER=DEFAULT_ANALYZER
|
||||
# BAIDU_VECTOR_DB_INVERTED_INDEX_PARSER_MODE=COARSE_MODE
|
||||
# BAIDU_VECTOR_DB_AUTO_BUILD_ROW_COUNT_INCREMENT=500
|
||||
# BAIDU_VECTOR_DB_AUTO_BUILD_ROW_COUNT_INCREMENT_RATIO=0.05
|
||||
# BAIDU_VECTOR_DB_REBUILD_INDEX_TIMEOUT_IN_SECONDS=300
|
||||
|
||||
# ------------------------------
|
||||
# Lindorm, Huawei Cloud, Upstash and Tablestore
|
||||
# ------------------------------
|
||||
# LINDORM_URL=http://localhost:30070
|
||||
# LINDORM_USERNAME=admin
|
||||
# LINDORM_USING_UGC=True
|
||||
# LINDORM_QUERY_TIMEOUT=1
|
||||
# HUAWEI_CLOUD_HOSTS=https://127.0.0.1:9200
|
||||
# HUAWEI_CLOUD_USER=admin
|
||||
# UPSTASH_VECTOR_URL=https://xxx-vector.upstash.io
|
||||
# TABLESTORE_ENDPOINT=https://instance-name.cn-hangzhou.ots.aliyuncs.com
|
||||
# TABLESTORE_INSTANCE_NAME=instance-name
|
||||
# TABLESTORE_NORMALIZE_FULLTEXT_BM25_SCORE=false
|
||||
|
||||
# ------------------------------
|
||||
# AnalyticDB, Alibaba Cloud MySQL and Relyt
|
||||
# ------------------------------
|
||||
# ANALYTICDB_REGION_ID=cn-hangzhou
|
||||
# ANALYTICDB_INSTANCE_ID=gp-ab123456
|
||||
# ANALYTICDB_ACCOUNT=testaccount
|
||||
# ANALYTICDB_NAMESPACE=dify
|
||||
# ANALYTICDB_HOST=gp-test.aliyuncs.com
|
||||
# ANALYTICDB_PORT=5432
|
||||
# ANALYTICDB_MIN_CONNECTION=1
|
||||
# ANALYTICDB_MAX_CONNECTION=5
|
||||
# ALIBABACLOUD_MYSQL_HOST=127.0.0.1
|
||||
# ALIBABACLOUD_MYSQL_PORT=3306
|
||||
# ALIBABACLOUD_MYSQL_USER=root
|
||||
# ALIBABACLOUD_MYSQL_DATABASE=dify
|
||||
# ALIBABACLOUD_MYSQL_MAX_CONNECTION=5
|
||||
# ALIBABACLOUD_MYSQL_HNSW_M=6
|
||||
# RELYT_HOST=db
|
||||
# RELYT_PORT=5432
|
||||
# RELYT_USER=postgres
|
||||
# RELYT_DATABASE=postgres
|
||||
|
||||
# ------------------------------
|
||||
# VikingDB and Hologres
|
||||
# ------------------------------
|
||||
# VIKINGDB_REGION=cn-shanghai
|
||||
# VIKINGDB_HOST=api-vikingdb.xxx.volces.com
|
||||
# VIKINGDB_SCHEME=http
|
||||
# VIKINGDB_CONNECTION_TIMEOUT=30
|
||||
# VIKINGDB_SOCKET_TIMEOUT=30
|
||||
# HOLOGRES_HOST=
|
||||
# HOLOGRES_PORT=80
|
||||
# HOLOGRES_DATABASE=
|
||||
# HOLOGRES_ACCESS_KEY_ID=
|
||||
# HOLOGRES_ACCESS_KEY_SECRET=
|
||||
# HOLOGRES_SCHEMA=public
|
||||
# HOLOGRES_TOKENIZER=jieba
|
||||
# HOLOGRES_DISTANCE_METHOD=Cosine
|
||||
# HOLOGRES_BASE_QUANTIZATION_TYPE=rabitq
|
||||
# HOLOGRES_MAX_DEGREE=64
|
||||
# HOLOGRES_EF_CONSTRUCTION=400
|
||||
@@ -1,574 +0,0 @@
|
||||
# ------------------------------
|
||||
# Shared API/Worker Configuration
|
||||
# ------------------------------
|
||||
|
||||
CONSOLE_WEB_URL=
|
||||
SERVICE_API_URL=
|
||||
TRIGGER_URL=http://localhost
|
||||
HUMAN_INPUT_IM_EVENT_TRANSPORT_MODE=WEBHOOK
|
||||
APP_WEB_URL=
|
||||
FILES_URL=
|
||||
INTERNAL_FILES_URL=
|
||||
LANG=C.UTF-8
|
||||
LC_ALL=C.UTF-8
|
||||
PYTHONIOENCODING=utf-8
|
||||
CHECK_UPDATE_URL=https://updates.dify.ai
|
||||
OPENAI_API_BASE=https://api.openai.com/v1
|
||||
MIGRATION_ENABLED=true
|
||||
FILES_ACCESS_TIMEOUT=300
|
||||
# System Features
|
||||
MARKETPLACE_ENABLED=true
|
||||
ENABLE_EMAIL_CODE_LOGIN=false
|
||||
EMAIL_CODE_LOGIN_TOKEN_EXPIRY_MINUTES=5
|
||||
EMAIL_CODE_LOGIN_MAX_ATTEMPTS=5
|
||||
ENABLE_EMAIL_PASSWORD_LOGIN=true
|
||||
ENABLE_SOCIAL_OAUTH_LOGIN=false
|
||||
# Remove `collaboration` from COMPOSE_PROFILES to stop the dedicated websocket service.
|
||||
ENABLE_COLLABORATION_MODE=true
|
||||
ALLOW_REGISTER=false
|
||||
ALLOW_CREATE_WORKSPACE=false
|
||||
ENABLE_CHANGE_EMAIL=true
|
||||
ENABLE_TRIAL_APP=false
|
||||
ENABLE_EXPLORE_BANNER=false
|
||||
ENABLE_LEARN_APP=true
|
||||
ENABLE_STEP_BY_STEP_TOUR=false
|
||||
ENABLE_SKILL=true
|
||||
RBAC_ENABLED=false
|
||||
ENABLE_LICENSE_EXPIRY_NOTICE=true
|
||||
CELERY_BROKER_URL=redis://:difyai123456@redis:6379/1
|
||||
# Optional long-running KnowledgeFS Celery rollout: set identically in every API, worker and Beat
|
||||
# process sharing this Redis broker. It must exceed the KnowledgeFS hard task limit (7230s by
|
||||
# default). Keep unset to preserve Celery's existing default when this rollout is disabled.
|
||||
# CELERY_BROKER_VISIBILITY_TIMEOUT=10800
|
||||
# KNOWLEDGE_FS_BACKGROUND_WORKER_ENABLED=true
|
||||
# KNOWLEDGE_FS_BACKGROUND_POLL_INTERVAL_SECONDS=5
|
||||
CELERY_TASK_ANNOTATIONS=null
|
||||
AZURE_BLOB_ACCOUNT_URL=https://<your_account_name>.blob.core.windows.net
|
||||
SUPABASE_URL=your-server-url
|
||||
TIDB_ON_QDRANT_URL=http://127.0.0.1
|
||||
TIDB_ON_QDRANT_API_KEY=dify
|
||||
TIDB_API_URL=http://127.0.0.1
|
||||
TIDB_IAM_API_URL=http://127.0.0.1
|
||||
TIDB_REGION=regions/aws-us-east-1
|
||||
TIDB_PROJECT_ID=dify
|
||||
TIDB_SPEND_LIMIT=100
|
||||
TENCENT_VECTOR_DB_URL=http://127.0.0.1
|
||||
TENCENT_VECTOR_DB_API_KEY=dify
|
||||
LINDORM_URL=http://localhost:30070
|
||||
LINDORM_USERNAME=admin
|
||||
UPSTASH_VECTOR_URL=https://xxx-vector.upstash.io
|
||||
UPLOAD_FILE_SIZE_LIMIT=15
|
||||
KNOWLEDGE_UPLOAD_FILE_SIZE_LIMIT_FOR_PAID_PLAN=15
|
||||
UPLOAD_FILE_BATCH_LIMIT=5
|
||||
UPLOAD_FILE_EXTENSION_BLACKLIST=
|
||||
SINGLE_CHUNK_ATTACHMENT_LIMIT=10
|
||||
IMAGE_FILE_BATCH_LIMIT=10
|
||||
ATTACHMENT_IMAGE_FILE_SIZE_LIMIT=2
|
||||
ATTACHMENT_IMAGE_DOWNLOAD_TIMEOUT=60
|
||||
ETL_TYPE=dify
|
||||
UNSTRUCTURED_API_URL=
|
||||
MULTIMODAL_SEND_FORMAT=base64
|
||||
UPLOAD_IMAGE_FILE_SIZE_LIMIT=10
|
||||
UPLOAD_VIDEO_FILE_SIZE_LIMIT=100
|
||||
UPLOAD_AUDIO_FILE_SIZE_LIMIT=50
|
||||
UPLOAD_SKILL_FILE_SIZE_LIMIT=50
|
||||
SKILL_PACKAGE_MAX_UNCOMPRESSED_BYTES=209715200
|
||||
SKILL_PACKAGE_MAX_ENTRIES=5000
|
||||
SKILL_PACKAGE_MAX_SKILL_MD_BYTES=1048576
|
||||
AGENT_PACKAGE_MAX_BYTES=536870912
|
||||
AGENT_PACKAGE_MAX_MANIFEST_BYTES=5242880
|
||||
AGENT_PACKAGE_MAX_ENTRIES=5000
|
||||
APP_PACKAGE_MAX_WORKFLOW_TOOLS=20
|
||||
API_SENTRY_DSN=
|
||||
API_SENTRY_TRACES_SAMPLE_RATE=1.0
|
||||
API_SENTRY_PROFILES_SAMPLE_RATE=1.0
|
||||
WEB_SENTRY_DSN=
|
||||
PLUGIN_SENTRY_ENABLED=false
|
||||
PLUGIN_SENTRY_DSN=
|
||||
NOTION_INTEGRATION_TYPE=public
|
||||
RESEND_API_URL=https://api.resend.com
|
||||
SSRF_PROXY_HTTP_URL=http://ssrf_proxy:3128
|
||||
SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128
|
||||
PGDATA=/var/lib/postgresql/data/pgdata
|
||||
PLUGIN_MAX_PACKAGE_SIZE=52428800
|
||||
PLUGIN_MAX_FILE_SIZE=52428800
|
||||
PLUGIN_MODEL_SCHEMA_CACHE_TTL=3600
|
||||
PLUGIN_MODEL_PROVIDERS_CACHE_ENABLED=true
|
||||
PLUGIN_MODEL_PROVIDERS_CACHE_TTL=86400
|
||||
# Comma-separated marketplace plugin IDs whose latest versions are installed for newly registered users.
|
||||
# Example: langgenius/openai,langgenius/gemini
|
||||
NEW_USER_DEFAULT_PLUGIN_IDS=
|
||||
# Comma-separated model_type:provider:model entries assigned after default plugins finish installing.
|
||||
# Example: llm:langgenius/openai/openai:gpt-4o-mini,text-embedding:langgenius/openai/openai:text-embedding-3-small
|
||||
NEW_USER_DEFAULT_MODELS=
|
||||
ENDPOINT_URL_TEMPLATE=http://localhost/e/{hook_id}
|
||||
LOG_LEVEL=INFO
|
||||
LOG_OUTPUT_FORMAT=text
|
||||
LOG_FILE=/app/logs/server.log
|
||||
LOG_FILE_MAX_SIZE=20
|
||||
LOG_FILE_BACKUP_COUNT=5
|
||||
LOG_DATEFORMAT=%Y-%m-%d %H:%M:%S
|
||||
LOG_TZ=UTC
|
||||
DEBUG=false
|
||||
FLASK_DEBUG=false
|
||||
ENABLE_REQUEST_LOGGING=False
|
||||
# Application-level Agent tracing; also enable the collector in dify-agent.env.
|
||||
OPS_AGENT_TRACE_ENABLED=false
|
||||
ENABLE_APPLICATION_TRACE_RECONCILE_TASK=true
|
||||
# Shared by API, workers, and Beat. Keep separate from legacy ops_trace during upgrades.
|
||||
OPS_TRACE_QUEUE=ops_trace_v2
|
||||
# Attempts to send one trace while its provider is temporarily unavailable.
|
||||
OPS_TRACE_EXPORT_MAX_ATTEMPTS=6
|
||||
# Daily cleanup of trace payloads an interrupted delivery left in storage.
|
||||
ENABLE_TRACE_PAYLOAD_SWEEP_TASK=true
|
||||
WORKFLOW_LOG_CLEANUP_ENABLED=false
|
||||
WORKFLOW_LOG_RETENTION_DAYS=30
|
||||
WORKFLOW_LOG_CLEANUP_BATCH_SIZE=100
|
||||
WORKFLOW_LOG_CLEANUP_SPECIFIC_WORKFLOW_IDS=
|
||||
EXPOSE_PLUGIN_DEBUGGING_HOST=localhost
|
||||
EXPOSE_PLUGIN_DEBUGGING_PORT=5003
|
||||
DEPLOY_ENV=PRODUCTION
|
||||
DEPLOYMENT_EDITION=COMMUNITY
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=60
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||
APP_DEFAULT_ACTIVE_REQUESTS=0
|
||||
APP_MAX_ACTIVE_REQUESTS=0
|
||||
# Agent backend client settings shared by API and worker processes.
|
||||
AGENT_BACKEND_STREAM_READ_TIMEOUT_SECONDS=30
|
||||
AGENT_BACKEND_STREAM_MAX_RECONNECTS=3
|
||||
# Client timeout for Agent backend calls that may carry a Home Snapshot transfer.
|
||||
# Must stay above DIFY_AGENT_ENTERPRISE_SANDBOX_SNAPSHOT_TIMEOUT on the Agent backend.
|
||||
AGENT_BACKEND_HOME_SNAPSHOT_TIMEOUT_SECONDS=45
|
||||
# Independent E2B accounting, collected only by API Celery Beat/workers.
|
||||
# Uses OPS_TRACE_QUEUE; business binding operations never call metering.
|
||||
# Enable after migrations. START_AT is an immutable, whole-second UTC T0.
|
||||
AGENT_SANDBOX_METERING_ENABLED=false
|
||||
AGENT_SANDBOX_METERING_PROJECT_ID=
|
||||
AGENT_SANDBOX_METERING_START_AT=
|
||||
AGENT_SANDBOX_METERING_INTERVAL_SECONDS=60
|
||||
# Outer execution limit for Agent Apps. Agent Backend may stop the internal
|
||||
# model/tool loop sooner when DIFY_AGENT_RUN_TIMEOUT_SECONDS is lower.
|
||||
APP_MAX_EXECUTION_TIME=3600
|
||||
DIFY_BIND_ADDRESS=0.0.0.0
|
||||
DIFY_PORT=5001
|
||||
SERVER_WORKER_AMOUNT=1
|
||||
SERVER_WORKER_CLASS=gevent
|
||||
SERVER_WORKER_CONNECTIONS=10
|
||||
API_WEBSOCKET_WORKER_AMOUNT=1
|
||||
API_WEBSOCKET_WORKER_CLASS=geventwebsocket.gunicorn.workers.GeventWebSocketWorker
|
||||
API_WEBSOCKET_WORKER_CONNECTIONS=1000
|
||||
API_WEBSOCKET_GUNICORN_TIMEOUT=360
|
||||
CELERY_SENTINEL_PASSWORD=
|
||||
S3_ACCESS_KEY=
|
||||
S3_SECRET_KEY=
|
||||
ARCHIVE_STORAGE_ACCESS_KEY=
|
||||
ARCHIVE_STORAGE_SECRET_KEY=
|
||||
AZURE_BLOB_ACCOUNT_KEY=difyai
|
||||
ALIYUN_OSS_ACCESS_KEY=your-access-key
|
||||
ALIYUN_OSS_SECRET_KEY=your-secret-key
|
||||
TENCENT_COS_SECRET_KEY=your-secret-key
|
||||
TENCENT_COS_SECRET_ID=your-secret-id
|
||||
OCI_ACCESS_KEY=your-access-key
|
||||
OCI_SECRET_KEY=your-secret-key
|
||||
HUAWEI_OBS_SECRET_KEY=your-secret-key
|
||||
HUAWEI_OBS_ACCESS_KEY=your-access-key
|
||||
VOLCENGINE_TOS_SECRET_KEY=your-secret-key
|
||||
VOLCENGINE_TOS_ACCESS_KEY=your-access-key
|
||||
BAIDU_OBS_SECRET_KEY=your-secret-key
|
||||
BAIDU_OBS_ACCESS_KEY=your-access-key
|
||||
SUPABASE_API_KEY=your-access-key
|
||||
ALIBABACLOUD_MYSQL_PASSWORD=difyai123456
|
||||
RELYT_PASSWORD=difyai123456
|
||||
LINDORM_PASSWORD=admin
|
||||
LINDORM_USING_UGC=True
|
||||
LINDORM_QUERY_TIMEOUT=1
|
||||
HUAWEI_CLOUD_PASSWORD=admin
|
||||
UPSTASH_VECTOR_TOKEN=dify
|
||||
TABLESTORE_ACCESS_KEY_ID=xxx
|
||||
TABLESTORE_ACCESS_KEY_SECRET=xxx
|
||||
TABLESTORE_NORMALIZE_FULLTEXT_BM25_SCORE=false
|
||||
CLICKZETTA_PASSWORD=
|
||||
CLICKZETTA_INSTANCE=
|
||||
CLICKZETTA_SERVICE=api.clickzetta.com
|
||||
CLICKZETTA_WORKSPACE=quick_start
|
||||
CLICKZETTA_VCLUSTER=default_ap
|
||||
CLICKZETTA_SCHEMA=dify
|
||||
CLICKZETTA_BATCH_SIZE=100
|
||||
CLICKZETTA_ENABLE_INVERTED_INDEX=true
|
||||
CLICKZETTA_ANALYZER_TYPE=chinese
|
||||
CLICKZETTA_ANALYZER_MODE=smart
|
||||
UNSTRUCTURED_API_KEY=
|
||||
SCARF_NO_ANALYTICS=true
|
||||
PLUGIN_BASED_TOKEN_COUNTING_ENABLED=false
|
||||
NOTION_CLIENT_SECRET=
|
||||
NOTION_CLIENT_ID=
|
||||
NOTION_INTERNAL_SECRET=
|
||||
MAIL_TYPE=resend
|
||||
MAIL_DEFAULT_SEND_FROM=
|
||||
RESEND_API_KEY=your-resend-api-key
|
||||
SMTP_SERVER=
|
||||
SMTP_PORT=465
|
||||
SMTP_USERNAME=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_USE_TLS=true
|
||||
SMTP_OPPORTUNISTIC_TLS=false
|
||||
SMTP_LOCAL_HOSTNAME=
|
||||
SENDGRID_API_KEY=
|
||||
INVITE_EXPIRY_HOURS=72
|
||||
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
|
||||
EMAIL_REGISTER_TOKEN_EXPIRY_MINUTES=5
|
||||
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES=5
|
||||
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES=5
|
||||
CODE_EXECUTION_ENDPOINT=http://sandbox:8194
|
||||
CODE_EXECUTION_API_KEY=dify-sandbox
|
||||
CODE_EXECUTION_SSL_VERIFY=True
|
||||
CODE_EXECUTION_POOL_MAX_CONNECTIONS=100
|
||||
CODE_EXECUTION_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
CODE_EXECUTION_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
CODE_MAX_NUMBER=9223372036854775807
|
||||
CODE_MIN_NUMBER=-9223372036854775808
|
||||
CODE_MAX_DEPTH=5
|
||||
CODE_MAX_PRECISION=20
|
||||
CODE_MAX_STRING_LENGTH=400000
|
||||
CODE_MAX_STRING_ARRAY_LENGTH=30
|
||||
CODE_MAX_OBJECT_ARRAY_LENGTH=30
|
||||
CODE_MAX_NUMBER_ARRAY_LENGTH=1000
|
||||
CODE_EXECUTION_CONNECT_TIMEOUT=10
|
||||
CODE_EXECUTION_READ_TIMEOUT=60
|
||||
CODE_EXECUTION_WRITE_TIMEOUT=10
|
||||
TEMPLATE_TRANSFORM_MAX_LENGTH=400000
|
||||
WORKFLOW_MAX_EXECUTION_STEPS=500
|
||||
# Outer execution limit for Workflow and Chatflow callers. Agent Backend may
|
||||
# stop the internal model/tool loop sooner when its run timeout is lower.
|
||||
# To allow all Agent call paths to run for one hour, set this value,
|
||||
# APP_MAX_EXECUTION_TIME, and DIFY_AGENT_RUN_TIMEOUT_SECONDS to at least 3600.
|
||||
WORKFLOW_MAX_EXECUTION_TIME=3600
|
||||
WORKFLOW_CALL_MAX_DEPTH=5
|
||||
MAX_VARIABLE_SIZE=204800
|
||||
WORKFLOW_GENERATOR_NODE_BUILDER_MAX_WORKERS=6
|
||||
WORKFLOW_FILE_UPLOAD_LIMIT=10
|
||||
GRAPH_ENGINE_MAX_WORKERS=10
|
||||
ALIYUN_SLS_ACCESS_KEY_ID=
|
||||
ALIYUN_SLS_ACCESS_KEY_SECRET=
|
||||
WEBHOOK_REQUEST_BODY_MAX_SIZE=10485760
|
||||
# Bare API default. Compose enables this for its API services behind Nginx.
|
||||
# Override Compose through docker/.env, the shell, or a Compose override, not this env_file.
|
||||
# See docker/README.md#client-ip-and-trusted-proxies before exposing the API directly.
|
||||
RESPECT_XFORWARD_HEADERS_ENABLED=false
|
||||
SSRF_HTTP_PORT=3128
|
||||
SSRF_COREDUMP_DIR=/var/spool/squid
|
||||
SSRF_DEFAULT_TIME_OUT=5
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||
SSRF_DEFAULT_READ_TIME_OUT=5
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT=5
|
||||
SSRF_POOL_MAX_CONNECTIONS=100
|
||||
SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
SSRF_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
PLUGIN_AWS_ACCESS_KEY=
|
||||
PLUGIN_AWS_SECRET_KEY=
|
||||
PLUGIN_AWS_REGION=
|
||||
PLUGIN_TENCENT_COS_SECRET_KEY=
|
||||
PLUGIN_TENCENT_COS_SECRET_ID=
|
||||
PLUGIN_ALIYUN_OSS_ACCESS_KEY_ID=
|
||||
PLUGIN_ALIYUN_OSS_ACCESS_KEY_SECRET=
|
||||
PLUGIN_VOLCENGINE_TOS_ACCESS_KEY=
|
||||
PLUGIN_VOLCENGINE_TOS_SECRET_KEY=
|
||||
OTLP_API_KEY=
|
||||
OTEL_EXPORTER_OTLP_PROTOCOL=
|
||||
OTEL_EXPORTER_TYPE=otlp
|
||||
OTEL_SAMPLING_RATE=0.1
|
||||
OTEL_BATCH_EXPORT_SCHEDULE_DELAY=5000
|
||||
OTEL_MAX_QUEUE_SIZE=2048
|
||||
OTEL_MAX_EXPORT_BATCH_SIZE=512
|
||||
OTEL_METRIC_EXPORT_INTERVAL=60000
|
||||
OTEL_BATCH_EXPORT_TIMEOUT=10000
|
||||
OTEL_METRIC_EXPORT_TIMEOUT=30000
|
||||
QUEUE_MONITOR_THRESHOLD=200
|
||||
QUEUE_MONITOR_ALERT_EMAILS=
|
||||
QUEUE_MONITOR_INTERVAL=30
|
||||
SWAGGER_UI_ENABLED=false
|
||||
SWAGGER_UI_PATH=/swagger-ui.html
|
||||
OPENAPI_ENABLED=false
|
||||
OPENAPI_CORS_ALLOW_ORIGINS=
|
||||
OPENAPI_KNOWN_CLIENT_IDS=difyctl
|
||||
OPENAPI_RATE_LIMIT_PER_TOKEN=60
|
||||
DEVICE_FLOW_APPROVE_RATE_LIMIT_PER_HOUR=10
|
||||
ENABLE_OAUTH_BEARER=false
|
||||
DSL_EXPORT_ENCRYPT_DATASET_ID=true
|
||||
DATASET_MAX_SEGMENTS_PER_REQUEST=0
|
||||
ENABLE_CLEAN_EMBEDDING_CACHE_TASK=false
|
||||
ENABLE_CLEAN_UNUSED_DATASETS_TASK=false
|
||||
ENABLE_CREATE_TIDB_SERVERLESS_TASK=false
|
||||
ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK=false
|
||||
ENABLE_CLEAN_MESSAGES=false
|
||||
ENABLE_WORKFLOW_RUN_CLEANUP_TASK=false
|
||||
ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK=false
|
||||
ENABLE_DATASETS_QUEUE_MONITOR=false
|
||||
ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK=true
|
||||
ENABLE_WORKFLOW_SCHEDULE_POLLER_TASK=true
|
||||
WORKFLOW_SCHEDULE_POLLER_INTERVAL=1
|
||||
WORKFLOW_SCHEDULE_POLLER_BATCH_SIZE=100
|
||||
WORKFLOW_SCHEDULE_MAX_DISPATCH_PER_TICK=0
|
||||
TENANT_ISOLATED_TASK_CONCURRENCY=1
|
||||
ANNOTATION_IMPORT_FILE_SIZE_LIMIT=2
|
||||
ANNOTATION_IMPORT_MAX_RECORDS=10000
|
||||
ANNOTATION_IMPORT_MIN_RECORDS=1
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_MINUTE=5
|
||||
ANNOTATION_IMPORT_RATE_LIMIT_PER_HOUR=20
|
||||
ANNOTATION_IMPORT_MAX_CONCURRENT=5
|
||||
CREATORS_PLATFORM_FEATURES_ENABLED=true
|
||||
CREATORS_PLATFORM_API_URL=https://creators.dify.ai
|
||||
CREATORS_PLATFORM_OAUTH_CLIENT_ID=
|
||||
TIDB_VECTOR_DATABASE=dify
|
||||
ALIBABACLOUD_MYSQL_HOST=127.0.0.1
|
||||
ALIBABACLOUD_MYSQL_PORT=3306
|
||||
ALIBABACLOUD_MYSQL_USER=root
|
||||
ALIBABACLOUD_MYSQL_DATABASE=dify
|
||||
ALIBABACLOUD_MYSQL_MAX_CONNECTION=5
|
||||
ALIBABACLOUD_MYSQL_HNSW_M=6
|
||||
RELYT_DATABASE=postgres
|
||||
TENCENT_VECTOR_DB_DATABASE=dify
|
||||
BAIDU_VECTOR_DB_DATABASE=dify
|
||||
EXPOSE_PLUGIN_DAEMON_PORT=5002
|
||||
GUNICORN_TIMEOUT=360
|
||||
# Must stay above the idle connection reuse window of the HTTP clients that
|
||||
# pool connections to this server. Node's global fetch (undici) keeps a socket
|
||||
# idle for 4s before dropping it, so a shorter value here lets the server close
|
||||
# a connection the client still considers reusable, which surfaces as
|
||||
# intermittent ECONNRESET on server-side rendering. 0 disables keep-alive.
|
||||
GUNICORN_KEEP_ALIVE=10
|
||||
CELERY_WORKER_AMOUNT=
|
||||
CELERY_AUTO_SCALE=false
|
||||
CELERY_MAX_WORKERS=
|
||||
CELERY_MIN_WORKERS=
|
||||
API_TOOL_DEFAULT_CONNECT_TIMEOUT=10
|
||||
API_TOOL_DEFAULT_READ_TIMEOUT=60
|
||||
CELERY_BACKEND=redis
|
||||
CELERY_USE_SENTINEL=false
|
||||
CELERY_SENTINEL_MASTER_NAME=
|
||||
CELERY_SENTINEL_SOCKET_TIMEOUT=0.1
|
||||
WEB_API_CORS_ALLOW_ORIGINS=*
|
||||
CONSOLE_CORS_ALLOW_ORIGINS=*
|
||||
WEBSOCKET_MAX_HTTP_BUFFER_SIZE=10485760
|
||||
COOKIE_DOMAIN=
|
||||
OPENDAL_SCHEME=fs
|
||||
OPENDAL_FS_ROOT=storage
|
||||
CLICKZETTA_VOLUME_TYPE=user
|
||||
CLICKZETTA_VOLUME_NAME=
|
||||
CLICKZETTA_VOLUME_TABLE_PREFIX=dataset_
|
||||
CLICKZETTA_VOLUME_DIFY_PREFIX=dify_km
|
||||
S3_ENDPOINT=
|
||||
S3_REGION=us-east-1
|
||||
S3_BUCKET_NAME=difyai
|
||||
S3_ADDRESS_STYLE=auto
|
||||
S3_USE_AWS_MANAGED_IAM=false
|
||||
ARCHIVE_STORAGE_ENABLED=false
|
||||
ARCHIVE_STORAGE_ENDPOINT=
|
||||
ARCHIVE_STORAGE_ARCHIVE_BUCKET=
|
||||
ARCHIVE_STORAGE_EXPORT_BUCKET=
|
||||
ARCHIVE_STORAGE_REGION=auto
|
||||
ARCHIVE_STORAGE_ADDRESS_STYLE=path
|
||||
AZURE_BLOB_ACCOUNT_NAME=difyai
|
||||
AZURE_BLOB_CONTAINER_NAME=difyai-container
|
||||
AZURE_KEYVAULT_VAULT_URL=
|
||||
AZURE_KEYVAULT_KEY_SIZE=2048
|
||||
AZURE_KEYVAULT_ROTATION_INTERVAL_DAYS=
|
||||
GOOGLE_STORAGE_BUCKET_NAME=your-bucket-name
|
||||
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64=
|
||||
ALIYUN_OSS_BUCKET_NAME=your-bucket-name
|
||||
ALIYUN_OSS_ENDPOINT=https://oss-ap-southeast-1-internal.aliyuncs.com
|
||||
ALIYUN_OSS_REGION=ap-southeast-1
|
||||
ALIYUN_OSS_AUTH_VERSION=v4
|
||||
ALIYUN_OSS_PATH=your-path
|
||||
ALIYUN_CLOUDBOX_ID=your-cloudbox-id
|
||||
TENCENT_COS_BUCKET_NAME=your-bucket-name
|
||||
TENCENT_COS_REGION=your-region
|
||||
TENCENT_COS_SCHEME=your-scheme
|
||||
TENCENT_COS_CUSTOM_DOMAIN=your-custom-domain
|
||||
OCI_ENDPOINT=https://your-object-storage-namespace.compat.objectstorage.us-ashburn-1.oraclecloud.com
|
||||
OCI_BUCKET_NAME=your-bucket-name
|
||||
OCI_REGION=us-ashburn-1
|
||||
HUAWEI_OBS_BUCKET_NAME=your-bucket-name
|
||||
HUAWEI_OBS_SERVER=your-server-url
|
||||
HUAWEI_OBS_PATH_STYLE=false
|
||||
VOLCENGINE_TOS_BUCKET_NAME=your-bucket-name
|
||||
VOLCENGINE_TOS_ENDPOINT=your-server-url
|
||||
VOLCENGINE_TOS_REGION=your-region
|
||||
BAIDU_OBS_BUCKET_NAME=your-bucket-name
|
||||
BAIDU_OBS_ENDPOINT=your-server-url
|
||||
SUPABASE_BUCKET_NAME=your-bucket-name
|
||||
TENCENT_VECTOR_DB_TIMEOUT=30
|
||||
TENCENT_VECTOR_DB_USERNAME=dify
|
||||
TENCENT_VECTOR_DB_SHARD=1
|
||||
TENCENT_VECTOR_DB_REPLICAS=2
|
||||
TENCENT_VECTOR_DB_ENABLE_HYBRID_SEARCH=false
|
||||
BAIDU_VECTOR_DB_ENDPOINT=http://127.0.0.1:5287
|
||||
BAIDU_VECTOR_DB_CONNECTION_TIMEOUT_MS=30000
|
||||
BAIDU_VECTOR_DB_ACCOUNT=root
|
||||
BAIDU_VECTOR_DB_API_KEY=dify
|
||||
BAIDU_VECTOR_DB_SHARD=1
|
||||
BAIDU_VECTOR_DB_REPLICAS=3
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_ANALYZER=DEFAULT_ANALYZER
|
||||
BAIDU_VECTOR_DB_INVERTED_INDEX_PARSER_MODE=COARSE_MODE
|
||||
BAIDU_VECTOR_DB_AUTO_BUILD_ROW_COUNT_INCREMENT=500
|
||||
BAIDU_VECTOR_DB_AUTO_BUILD_ROW_COUNT_INCREMENT_RATIO=0.05
|
||||
BAIDU_VECTOR_DB_REBUILD_INDEX_TIMEOUT_IN_SECONDS=300
|
||||
HUAWEI_CLOUD_HOSTS=https://127.0.0.1:9200
|
||||
HUAWEI_CLOUD_USER=admin
|
||||
WORKFLOW_NODE_EXECUTION_STORAGE=rdbms
|
||||
CORE_WORKFLOW_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_execution_repository.SQLAlchemyWorkflowExecutionRepository
|
||||
CORE_WORKFLOW_NODE_EXECUTION_REPOSITORY=core.repositories.sqlalchemy_workflow_node_execution_repository.SQLAlchemyWorkflowNodeExecutionRepository
|
||||
API_WORKFLOW_RUN_REPOSITORY=repositories.sqlalchemy_api_workflow_run_repository.DifyAPISQLAlchemyWorkflowRunRepository
|
||||
API_WORKFLOW_NODE_EXECUTION_REPOSITORY=repositories.sqlalchemy_api_workflow_node_execution_repository.DifyAPISQLAlchemyWorkflowNodeExecutionRepository
|
||||
ALIYUN_SLS_ENDPOINT=
|
||||
ALIYUN_SLS_REGION=
|
||||
ALIYUN_SLS_PROJECT_NAME=
|
||||
ALIYUN_SLS_LOGSTORE_TTL=365
|
||||
LOGSTORE_DUAL_WRITE_ENABLED=false
|
||||
LOGSTORE_DUAL_READ_ENABLED=true
|
||||
LOGSTORE_ENABLE_PUT_GRAPH_FIELD=true
|
||||
HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760
|
||||
HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576
|
||||
HTTP_REQUEST_NODE_SSL_VERIFY=True
|
||||
HTTP_REQUEST_MAX_CONNECT_TIMEOUT=10
|
||||
HTTP_REQUEST_MAX_READ_TIMEOUT=600
|
||||
HTTP_REQUEST_MAX_WRITE_TIMEOUT=600
|
||||
PLUGIN_INSTALLED_PATH=plugin
|
||||
PLUGIN_PACKAGE_CACHE_PATH=plugin_packages
|
||||
PLUGIN_MEDIA_CACHE_PATH=assets
|
||||
PLUGIN_S3_USE_AWS=false
|
||||
PLUGIN_S3_USE_AWS_MANAGED_IAM=false
|
||||
PLUGIN_S3_ENDPOINT=
|
||||
PLUGIN_S3_USE_PATH_STYLE=false
|
||||
PLUGIN_AZURE_BLOB_STORAGE_CONTAINER_NAME=
|
||||
PLUGIN_AZURE_BLOB_STORAGE_CONNECTION_STRING=
|
||||
PLUGIN_TENCENT_COS_REGION=
|
||||
PLUGIN_ALIYUN_OSS_REGION=
|
||||
PLUGIN_ALIYUN_OSS_ENDPOINT=
|
||||
PLUGIN_ALIYUN_OSS_AUTH_VERSION=v4
|
||||
PLUGIN_ALIYUN_OSS_PATH=
|
||||
PLUGIN_VOLCENGINE_TOS_ENDPOINT=
|
||||
PLUGIN_VOLCENGINE_TOS_REGION=
|
||||
ENABLE_OTEL=false
|
||||
OTLP_TRACE_ENDPOINT=
|
||||
OTLP_METRIC_ENDPOINT=
|
||||
# Prefix used to create collection name in vector database
|
||||
OTLP_BASE_ENDPOINT=http://localhost:4318
|
||||
WEAVIATE_GRPC_ENDPOINT=grpc://weaviate:50051
|
||||
ANALYTICDB_KEY_ID=your-ak
|
||||
ANALYTICDB_KEY_SECRET=your-sk
|
||||
ANALYTICDB_REGION_ID=cn-hangzhou
|
||||
ANALYTICDB_INSTANCE_ID=gp-ab123456
|
||||
ANALYTICDB_ACCOUNT=testaccount
|
||||
ANALYTICDB_PASSWORD=testpassword
|
||||
ANALYTICDB_NAMESPACE=dify
|
||||
ANALYTICDB_NAMESPACE_PASSWORD=difypassword
|
||||
ANALYTICDB_HOST=gp-test.aliyuncs.com
|
||||
ANALYTICDB_PORT=5432
|
||||
ANALYTICDB_MIN_CONNECTION=1
|
||||
ANALYTICDB_MAX_CONNECTION=5
|
||||
TIDB_VECTOR_HOST=tidb
|
||||
TIDB_VECTOR_PORT=4000
|
||||
TIDB_VECTOR_USER=
|
||||
TIDB_VECTOR_PASSWORD=
|
||||
TIDB_VECTOR_ENABLE_FULLTEXT_SEARCH=false
|
||||
TIDB_ON_QDRANT_CLIENT_TIMEOUT=20
|
||||
TIDB_ON_QDRANT_GRPC_ENABLED=false
|
||||
TIDB_ON_QDRANT_GRPC_PORT=6334
|
||||
TIDB_ON_QDRANT_ESTIMATED_STORAGE_LIMITS_MB=sandbox:60,professional:6400,team:25600
|
||||
TIDB_PUBLIC_KEY=dify
|
||||
TIDB_PRIVATE_KEY=dify
|
||||
RELYT_HOST=db
|
||||
RELYT_PORT=5432
|
||||
RELYT_USER=postgres
|
||||
VIKINGDB_ACCESS_KEY=your-ak
|
||||
VIKINGDB_SECRET_KEY=your-sk
|
||||
VIKINGDB_REGION=cn-shanghai
|
||||
VIKINGDB_HOST=api-vikingdb.xxx.volces.com
|
||||
VIKINGDB_SCHEME=http
|
||||
VIKINGDB_CONNECTION_TIMEOUT=30
|
||||
VIKINGDB_SOCKET_TIMEOUT=30
|
||||
TABLESTORE_ENDPOINT=https://instance-name.cn-hangzhou.ots.aliyuncs.com
|
||||
TABLESTORE_INSTANCE_NAME=instance-name
|
||||
CLICKZETTA_USERNAME=
|
||||
CLICKZETTA_VECTOR_DISTANCE_FUNCTION=cosine_distance
|
||||
COMPOSE_PROFILES=${VECTOR_STORE:-weaviate},${DB_TYPE:-postgresql},collaboration
|
||||
EXPOSE_NGINX_PORT=80
|
||||
EXPOSE_NGINX_SSL_PORT=443
|
||||
POSITION_TOOL_PINS=
|
||||
POSITION_TOOL_INCLUDES=
|
||||
POSITION_TOOL_EXCLUDES=
|
||||
POSITION_PROVIDER_PINS=
|
||||
POSITION_PROVIDER_INCLUDES=
|
||||
POSITION_PROVIDER_EXCLUDES=
|
||||
CREATE_TIDB_SERVICE_JOB_ENABLED=false
|
||||
MAX_SUBMIT_COUNT=100
|
||||
|
||||
# Vector Store Configuration
|
||||
STORAGE_TYPE=opendal
|
||||
KEY_PROVIDER_TYPE=local
|
||||
VECTOR_STORE=weaviate
|
||||
VECTOR_INDEX_NAME_PREFIX=Vector_index
|
||||
WEAVIATE_ENDPOINT=http://weaviate:8080
|
||||
WEAVIATE_API_KEY=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_TOKENIZATION=word
|
||||
OCEANBASE_VECTOR_HOST=oceanbase
|
||||
OCEANBASE_VECTOR_PORT=2881
|
||||
OCEANBASE_VECTOR_USER=root@test
|
||||
OCEANBASE_VECTOR_PASSWORD=difyai123456
|
||||
OCEANBASE_VECTOR_DATABASE=test
|
||||
OCEANBASE_ENABLE_HYBRID_SEARCH=false
|
||||
OCEANBASE_FULLTEXT_PARSER=ik
|
||||
SEEKDB_MEMORY_LIMIT=2G
|
||||
QDRANT_URL=http://qdrant:6333
|
||||
QDRANT_API_KEY=difyai123456
|
||||
QDRANT_CLIENT_TIMEOUT=20
|
||||
QDRANT_GRPC_ENABLED=false
|
||||
QDRANT_GRPC_PORT=6334
|
||||
QDRANT_REPLICATION_FACTOR=1
|
||||
MILVUS_URI=http://host.docker.internal:19530
|
||||
MILVUS_TOKEN=
|
||||
MILVUS_USER=
|
||||
MILVUS_PASSWORD=
|
||||
MILVUS_ANALYZER_PARAMS=
|
||||
PGVECTOR_HOST=pgvector
|
||||
PGVECTOR_PORT=5432
|
||||
PGVECTOR_USER=postgres
|
||||
PGVECTOR_PASSWORD=difyai123456
|
||||
PGVECTOR_DATABASE=dify
|
||||
PGVECTOR_MIN_CONNECTION=1
|
||||
PGVECTOR_MAX_CONNECTION=5
|
||||
PGVECTOR_PG_BIGM=false
|
||||
PGVECTOR_PG_BIGM_VERSION=1.2-20240606
|
||||
|
||||
# Hologres Configuration
|
||||
HOLOGRES_HOST=
|
||||
HOLOGRES_PORT=80
|
||||
HOLOGRES_DATABASE=
|
||||
HOLOGRES_ACCESS_KEY_ID=
|
||||
HOLOGRES_ACCESS_KEY_SECRET=
|
||||
HOLOGRES_SCHEMA=public
|
||||
HOLOGRES_TOKENIZER=jieba
|
||||
HOLOGRES_DISTANCE_METHOD=Cosine
|
||||
HOLOGRES_BASE_QUANTIZATION_TYPE=rabitq
|
||||
HOLOGRES_MAX_DEGREE=64
|
||||
HOLOGRES_EF_CONSTRUCTION=400
|
||||
|
||||
# Milvus API Configuration
|
||||
MILVUS_DATABASE=
|
||||
MILVUS_ENABLE_HYBRID_SEARCH=False
|
||||
|
||||
# Human Input Task Configuration
|
||||
ENABLE_HUMAN_INPUT_TIMEOUT_TASK=true
|
||||
HUMAN_INPUT_TIMEOUT_TASK_INTERVAL=1
|
||||
|
||||
# Conversation cleanup recovery task
|
||||
ENABLE_CONVERSATION_CLEANUP_TASK=true
|
||||
CONVERSATION_CLEANUP_TASK_INTERVAL=5
|
||||
CONVERSATION_CLEANUP_BATCH_SIZE=100
|
||||
|
||||
# Nacos remote settings source HTTP timeouts (seconds).
|
||||
# Bound how long requests to the Nacos endpoint wait before failing, so a slow or
|
||||
# unresponsive Nacos server cannot stall API startup or token refresh.
|
||||
DIFY_ENV_NACOS_REQUEST_TIMEOUT=10.0
|
||||
DIFY_ENV_NACOS_CONNECT_TIMEOUT=3.0
|
||||
@@ -0,0 +1,60 @@
|
||||
# Defaults for web. Copy this file to web.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
CONSOLE_API_URL=${CONSOLE_API_URL:-}
|
||||
SERVER_CONSOLE_API_URL=${SERVER_CONSOLE_API_URL:-http://api:5001}
|
||||
APP_API_URL=${APP_API_URL:-}
|
||||
# Optional Cloud WebApp document admission. Enable only after the edge proxy
|
||||
# overwrites both X-Dify-Webapp-Client-Ip and X-Dify-Webapp-Proxy-Secret, Web is
|
||||
# private to that proxy, and the target Gateway enforces /api using trusted IPs.
|
||||
# Use the complete internal Gateway endpoint, never a direct Core API URL.
|
||||
# Example: http://gateway-public:8080/api/webapp/access-mode
|
||||
# WEBAPP_ACCESS_PREFLIGHT_URL=
|
||||
# Provision outside Git; must match the edge-injected secret. Never NEXT_PUBLIC.
|
||||
# WEBAPP_ACCESS_PREFLIGHT_PROXY_SECRET=
|
||||
WEB_SENTRY_DSN=${WEB_SENTRY_DSN:-}
|
||||
NEXT_PUBLIC_SOCKET_URL=${NEXT_PUBLIC_SOCKET_URL:-ws://localhost}
|
||||
EXPERIMENTAL_ENABLE_VINEXT=${EXPERIMENTAL_ENABLE_VINEXT:-false}
|
||||
LOOP_NODE_MAX_COUNT=${LOOP_NODE_MAX_COUNT:-100}
|
||||
MAX_TOOLS_NUM=${MAX_TOOLS_NUM:-10}
|
||||
MAX_PARALLEL_LIMIT=${MAX_PARALLEL_LIMIT:-10}
|
||||
MAX_ITERATIONS_NUM=${MAX_ITERATIONS_NUM:-99}
|
||||
TEXT_GENERATION_TIMEOUT_MS=${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
# WORKFLOW_GENERATION_TIMEOUT_MS=180000
|
||||
# ALLOW_INLINE_STYLES=false
|
||||
# Example: ()!*&()!*&-。.;;+=—
|
||||
# MARKDOWN_FORM_FIELD_NAME_EXTRA_CHARS=
|
||||
# Maximum length of Markdown form field names.
|
||||
# MARKDOWN_FORM_FIELD_NAME_MAX_LENGTH=128
|
||||
ALLOW_UNSAFE_DATA_SCHEME=${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MAX_TREE_DEPTH=${MAX_TREE_DEPTH:-50}
|
||||
MARKETPLACE_API_URL=${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
MARKETPLACE_URL=${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-4000}
|
||||
ALLOW_EMBED=${ALLOW_EMBED:-false}
|
||||
AMPLITUDE_API_KEY=${AMPLITUDE_API_KEY:-}
|
||||
TURNSTILE_SITE_KEY=${TURNSTILE_SITE_KEY:-}
|
||||
# COOKIEYES_SITE_KEY=
|
||||
ENABLE_WEBSITE_JINAREADER=${ENABLE_WEBSITE_JINAREADER:-true}
|
||||
ENABLE_WEBSITE_FIRECRAWL=${ENABLE_WEBSITE_FIRECRAWL:-true}
|
||||
ENABLE_WEBSITE_WATERCRAWL=${ENABLE_WEBSITE_WATERCRAWL:-true}
|
||||
# NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX=false
|
||||
# NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW=true
|
||||
|
||||
# Enable HITL IM, Contacts, V2 editing/migration and approval UI. Defaults to false.
|
||||
# When false, retain legacy V1 behavior and disable V2 entry points without converting saved data.
|
||||
# Restart the Web service and reload the page after changing this setting.
|
||||
# NEXT_PUBLIC_ENABLE_HITL_IM=false
|
||||
# Show Access Token settings to workspace owners. Disabled by default.
|
||||
# NEXT_PUBLIC_ENABLE_ACCESS_TOKEN=false
|
||||
NEXT_PUBLIC_ENABLE_AGENT_V2=${NEXT_PUBLIC_ENABLE_AGENT_V2:-true}
|
||||
# NEXT_PUBLIC_ENABLE_AGENT_V2_IN_CHATFLOW=false
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN=${NEXT_PUBLIC_COOKIE_DOMAIN:-}
|
||||
# NEXT_PUBLIC_BATCH_CONCURRENCY=5
|
||||
CSP_WHITELIST=${CSP_WHITELIST:-}
|
||||
TOP_K_MAX_VALUE=${TOP_K_MAX_VALUE:-10}
|
||||
NEXT_TELEMETRY_DISABLED=${NEXT_TELEMETRY_DISABLED:-0}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
SENTRY_DSN=${WEB_SENTRY_DSN:-}
|
||||
@@ -1,56 +0,0 @@
|
||||
# ------------------------------
|
||||
# Web Configuration
|
||||
# ------------------------------
|
||||
|
||||
CONSOLE_API_URL=
|
||||
SERVER_CONSOLE_API_URL=http://api:5001
|
||||
APP_API_URL=
|
||||
# Optional Cloud WebApp document admission. Enable only after the edge proxy
|
||||
# overwrites both X-Dify-Webapp-Client-Ip and X-Dify-Webapp-Proxy-Secret, Web is
|
||||
# private to that proxy, and the target Gateway enforces /api using trusted IPs.
|
||||
# Use the complete internal Gateway endpoint, never a direct Core API URL.
|
||||
# Example: http://gateway-public:8080/api/webapp/access-mode
|
||||
WEBAPP_ACCESS_PREFLIGHT_URL=
|
||||
# Provision outside Git; must match the edge-injected secret. Never NEXT_PUBLIC.
|
||||
WEBAPP_ACCESS_PREFLIGHT_PROXY_SECRET=
|
||||
SENTRY_DSN=
|
||||
NEXT_PUBLIC_SOCKET_URL=ws://localhost
|
||||
EXPERIMENTAL_ENABLE_VINEXT=false
|
||||
LOOP_NODE_MAX_COUNT=100
|
||||
MAX_TOOLS_NUM=10
|
||||
MAX_PARALLEL_LIMIT=10
|
||||
MAX_ITERATIONS_NUM=99
|
||||
TEXT_GENERATION_TIMEOUT_MS=60000
|
||||
WORKFLOW_GENERATION_TIMEOUT_MS=180000
|
||||
ALLOW_INLINE_STYLES=false
|
||||
# Example: ()!*&()!*&-。.;;+=—
|
||||
MARKDOWN_FORM_FIELD_NAME_EXTRA_CHARS=
|
||||
# Maximum length of Markdown form field names.
|
||||
MARKDOWN_FORM_FIELD_NAME_MAX_LENGTH=128
|
||||
ALLOW_UNSAFE_DATA_SCHEME=false
|
||||
MAX_TREE_DEPTH=50
|
||||
MARKETPLACE_API_URL=https://marketplace.dify.ai
|
||||
MARKETPLACE_URL=https://marketplace.dify.ai
|
||||
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=4000
|
||||
ALLOW_EMBED=false
|
||||
AMPLITUDE_API_KEY=
|
||||
TURNSTILE_SITE_KEY=
|
||||
COOKIEYES_SITE_KEY=
|
||||
ENABLE_WEBSITE_JINAREADER=true
|
||||
ENABLE_WEBSITE_FIRECRAWL=true
|
||||
ENABLE_WEBSITE_WATERCRAWL=true
|
||||
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX=false
|
||||
NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW=true
|
||||
|
||||
# Enable HITL IM, Contacts, V2 editing/migration and approval UI. Defaults to false.
|
||||
# When false, retain legacy V1 behavior and disable V2 entry points without converting saved data.
|
||||
# Restart the Web service and reload the page after changing this setting.
|
||||
NEXT_PUBLIC_ENABLE_HITL_IM=false
|
||||
# Show Access Token settings to workspace owners. Disabled by default.
|
||||
NEXT_PUBLIC_ENABLE_ACCESS_TOKEN=false
|
||||
NEXT_PUBLIC_ENABLE_AGENT_V2=true
|
||||
NEXT_PUBLIC_ENABLE_AGENT_V2_IN_CHATFLOW=false
|
||||
NEXT_PUBLIC_COOKIE_DOMAIN=
|
||||
NEXT_PUBLIC_BATCH_CONCURRENCY=5
|
||||
CSP_WHITELIST=
|
||||
TOP_K_MAX_VALUE=10
|
||||
@@ -0,0 +1,9 @@
|
||||
# Defaults for worker_beat. Copy this file to worker-beat.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# MODE is selected by the Compose service.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_DISABLED in docker/.env; Compose needs it before loading service files.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_INTERVAL in docker/.env; Compose needs it before loading service files.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_TIMEOUT in docker/.env; Compose needs it before loading service files.
|
||||
CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/1}
|
||||
@@ -1,8 +0,0 @@
|
||||
# ------------------------------
|
||||
# Worker Beat Configuration
|
||||
# ------------------------------
|
||||
|
||||
MODE=beat
|
||||
COMPOSE_WORKER_HEALTHCHECK_DISABLED=true
|
||||
COMPOSE_WORKER_HEALTHCHECK_INTERVAL=30s
|
||||
COMPOSE_WORKER_HEALTHCHECK_TIMEOUT=30s
|
||||
@@ -0,0 +1,29 @@
|
||||
# Defaults for worker. Copy this file to worker.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# MODE is selected by the Compose service.
|
||||
# CELERY_WORKER_CLASS=gevent
|
||||
API_SENTRY_DSN=${API_SENTRY_DSN:-}
|
||||
API_SENTRY_TRACES_SAMPLE_RATE=${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
API_SENTRY_PROFILES_SAMPLE_RATE=${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
PLUGIN_MAX_PACKAGE_SIZE=${PLUGIN_MAX_PACKAGE_SIZE:-52428800}
|
||||
# Set PLUGIN_DIFY_INNER_API_KEY in docker/.env; all callers must share the API's inner credential.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_DISABLED in docker/.env; Compose needs it before loading service files.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_INTERVAL in docker/.env; Compose needs it before loading service files.
|
||||
# Set COMPOSE_WORKER_HEALTHCHECK_TIMEOUT in docker/.env; Compose needs it before loading service files.
|
||||
DIFY_AGENT_API_TOKEN=${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
AGENT_BACKEND_BASE_URL=${AGENT_BACKEND_BASE_URL:-http://agent_backend:5050}
|
||||
CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://:${REDIS_PASSWORD:-difyai123456}@${REDIS_HOST:-redis}:${REDIS_PORT:-6379}/1}
|
||||
|
||||
# Worker autoscaling
|
||||
# CELERY_AUTO_SCALE=false
|
||||
# CELERY_MAX_WORKERS=
|
||||
# CELERY_MIN_WORKERS=
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
AGENT_BACKEND_API_TOKEN=${DIFY_AGENT_API_TOKEN:-dify-agent-run-token-for-dev-only}
|
||||
INNER_API_KEY_FOR_PLUGIN=${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1}
|
||||
SENTRY_DSN=${API_SENTRY_DSN:-}
|
||||
SENTRY_PROFILES_SAMPLE_RATE=${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0}
|
||||
SENTRY_TRACES_SAMPLE_RATE=${API_SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||
@@ -1,13 +0,0 @@
|
||||
# ------------------------------
|
||||
# Worker Configuration
|
||||
# ------------------------------
|
||||
|
||||
MODE=worker
|
||||
SENTRY_DSN=
|
||||
SENTRY_TRACES_SAMPLE_RATE=1.0
|
||||
SENTRY_PROFILES_SAMPLE_RATE=1.0
|
||||
PLUGIN_MAX_PACKAGE_SIZE=52428800
|
||||
INNER_API_KEY_FOR_PLUGIN=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
|
||||
COMPOSE_WORKER_HEALTHCHECK_DISABLED=true
|
||||
COMPOSE_WORKER_HEALTHCHECK_INTERVAL=30s
|
||||
COMPOSE_WORKER_HEALTHCHECK_TIMEOUT=30s
|
||||
@@ -0,0 +1,15 @@
|
||||
# Defaults for db_mysql. Copy this file to db-mysql.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
MYSQL_INNODB_LOG_FILE_SIZE=${MYSQL_INNODB_LOG_FILE_SIZE:-128M}
|
||||
MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT=${MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT:-2}
|
||||
MYSQL_MAX_CONNECTIONS=${MYSQL_MAX_CONNECTIONS:-1000}
|
||||
MYSQL_INNODB_BUFFER_POOL_SIZE=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M}
|
||||
# Set MYSQL_HOST_VOLUME in docker/.env; Compose needs it before loading service files.
|
||||
DB_DATABASE=${DB_DATABASE:-dify}
|
||||
DB_PASSWORD=${DB_PASSWORD:-difyai123456}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
MYSQL_DATABASE=${DB_DATABASE:-dify}
|
||||
MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-difyai123456}
|
||||
@@ -1,9 +0,0 @@
|
||||
# ------------------------------
|
||||
# Db Mysql Configuration
|
||||
# ------------------------------
|
||||
|
||||
MYSQL_INNODB_LOG_FILE_SIZE=128M
|
||||
MYSQL_INNODB_FLUSH_LOG_AT_TRX_COMMIT=2
|
||||
MYSQL_MAX_CONNECTIONS=1000
|
||||
MYSQL_INNODB_BUFFER_POOL_SIZE=512M
|
||||
MYSQL_HOST_VOLUME=./volumes/mysql/data
|
||||
@@ -0,0 +1,31 @@
|
||||
# Defaults for db_postgres. Copy this file to db-postgres.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
PGDATA=${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
# DB_TYPE=postgresql
|
||||
DB_USERNAME=${DB_USERNAME:-postgres}
|
||||
DB_PASSWORD=${DB_PASSWORD:-difyai123456}
|
||||
# DB_HOST=db_postgres
|
||||
# DB_PORT=5432
|
||||
DB_DATABASE=${DB_DATABASE:-dify}
|
||||
# SQLALCHEMY_POOL_SIZE=30
|
||||
# SQLALCHEMY_MAX_OVERFLOW=10
|
||||
# SQLALCHEMY_POOL_RECYCLE=3600
|
||||
# SQLALCHEMY_ECHO=false
|
||||
# SQLALCHEMY_POOL_PRE_PING=false
|
||||
# SQLALCHEMY_POOL_USE_LIFO=false
|
||||
# SQLALCHEMY_POOL_TIMEOUT=30
|
||||
# SQLALCHEMY_POOL_RESET_ON_RETURN=rollback
|
||||
POSTGRES_MAX_CONNECTIONS=${POSTGRES_MAX_CONNECTIONS:-200}
|
||||
POSTGRES_SHARED_BUFFERS=${POSTGRES_SHARED_BUFFERS:-128MB}
|
||||
POSTGRES_WORK_MEM=${POSTGRES_WORK_MEM:-4MB}
|
||||
POSTGRES_MAINTENANCE_WORK_MEM=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}
|
||||
POSTGRES_EFFECTIVE_CACHE_SIZE=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}
|
||||
POSTGRES_STATEMENT_TIMEOUT=${POSTGRES_STATEMENT_TIMEOUT:-0}
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT=${POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT:-0}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
POSTGRES_DB=${DB_DATABASE:-dify}
|
||||
POSTGRES_PASSWORD=${DB_PASSWORD:-difyai123456}
|
||||
POSTGRES_USER=${DB_USERNAME:-postgres}
|
||||
@@ -1,26 +0,0 @@
|
||||
# ------------------------------
|
||||
# Db Postgres Configuration
|
||||
# ------------------------------
|
||||
|
||||
PGDATA=/var/lib/postgresql/data/pgdata
|
||||
DB_TYPE=postgresql
|
||||
DB_USERNAME=postgres
|
||||
DB_PASSWORD=difyai123456
|
||||
DB_HOST=db_postgres
|
||||
DB_PORT=5432
|
||||
DB_DATABASE=dify
|
||||
SQLALCHEMY_POOL_SIZE=30
|
||||
SQLALCHEMY_MAX_OVERFLOW=10
|
||||
SQLALCHEMY_POOL_RECYCLE=3600
|
||||
SQLALCHEMY_ECHO=false
|
||||
SQLALCHEMY_POOL_PRE_PING=false
|
||||
SQLALCHEMY_POOL_USE_LIFO=false
|
||||
SQLALCHEMY_POOL_TIMEOUT=30
|
||||
SQLALCHEMY_POOL_RESET_ON_RETURN=rollback
|
||||
POSTGRES_MAX_CONNECTIONS=100
|
||||
POSTGRES_SHARED_BUFFERS=128MB
|
||||
POSTGRES_WORK_MEM=4MB
|
||||
POSTGRES_MAINTENANCE_WORK_MEM=64MB
|
||||
POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB
|
||||
POSTGRES_STATEMENT_TIMEOUT=0
|
||||
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT=0
|
||||
@@ -0,0 +1,42 @@
|
||||
# Defaults for redis. Copy this file to redis.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# REDIS_HOST=redis
|
||||
# REDIS_PORT=6379
|
||||
# REDIS_USERNAME=
|
||||
REDIS_PASSWORD=${REDIS_PASSWORD:-difyai123456}
|
||||
# REDIS_USE_SSL=false
|
||||
# REDIS_SSL_CERT_REQS=CERT_NONE
|
||||
# REDIS_SSL_CA_CERTS=
|
||||
# REDIS_SSL_CERTFILE=
|
||||
# REDIS_SSL_KEYFILE=
|
||||
# REDIS_DB=0
|
||||
# REDIS_KEY_PREFIX=
|
||||
# REDIS_MAX_CONNECTIONS=
|
||||
# REDIS_USE_SENTINEL=false
|
||||
# REDIS_SENTINELS=
|
||||
# REDIS_SENTINEL_SERVICE_NAME=
|
||||
# REDIS_SENTINEL_USERNAME=
|
||||
# REDIS_SENTINEL_PASSWORD=
|
||||
# REDIS_SENTINEL_SOCKET_TIMEOUT=0.1
|
||||
# REDIS_USE_CLUSTERS=false
|
||||
# REDIS_CLUSTERS=
|
||||
# REDIS_CLUSTERS_PASSWORD=
|
||||
# REDIS_RETRY_RETRIES=3
|
||||
# REDIS_RETRY_BACKOFF_BASE=1.0
|
||||
# REDIS_RETRY_BACKOFF_CAP=10.0
|
||||
# REDIS_SOCKET_TIMEOUT=5.0
|
||||
# REDIS_SOCKET_CONNECT_TIMEOUT=5.0
|
||||
# REDIS_HEALTH_CHECK_INTERVAL=30
|
||||
# REDIS_KEEPALIVE=true
|
||||
# REDIS_KEEPALIVE_IDLE=30
|
||||
# REDIS_KEEPALIVE_INTERVAL=10
|
||||
# REDIS_KEEPALIVE_COUNT=10
|
||||
# EVENT_BUS_REDIS_URL=
|
||||
# EVENT_BUS_REDIS_CHANNEL_TYPE=pubsub
|
||||
# EVENT_BUS_REDIS_USE_CLUSTERS=false
|
||||
# BROKER_USE_SSL=false
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
REDISCLI_AUTH=${REDIS_PASSWORD:-difyai123456}
|
||||
@@ -1,39 +0,0 @@
|
||||
# ------------------------------
|
||||
# Redis Configuration
|
||||
# ------------------------------
|
||||
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_USERNAME=
|
||||
REDIS_PASSWORD=difyai123456
|
||||
REDIS_USE_SSL=false
|
||||
REDIS_SSL_CERT_REQS=CERT_NONE
|
||||
REDIS_SSL_CA_CERTS=
|
||||
REDIS_SSL_CERTFILE=
|
||||
REDIS_SSL_KEYFILE=
|
||||
REDIS_DB=0
|
||||
REDIS_KEY_PREFIX=
|
||||
REDIS_MAX_CONNECTIONS=
|
||||
REDIS_USE_SENTINEL=false
|
||||
REDIS_SENTINELS=
|
||||
REDIS_SENTINEL_SERVICE_NAME=
|
||||
REDIS_SENTINEL_USERNAME=
|
||||
REDIS_SENTINEL_PASSWORD=
|
||||
REDIS_SENTINEL_SOCKET_TIMEOUT=0.1
|
||||
REDIS_USE_CLUSTERS=false
|
||||
REDIS_CLUSTERS=
|
||||
REDIS_CLUSTERS_PASSWORD=
|
||||
REDIS_RETRY_RETRIES=3
|
||||
REDIS_RETRY_BACKOFF_BASE=1.0
|
||||
REDIS_RETRY_BACKOFF_CAP=10.0
|
||||
REDIS_SOCKET_TIMEOUT=5.0
|
||||
REDIS_SOCKET_CONNECT_TIMEOUT=5.0
|
||||
REDIS_HEALTH_CHECK_INTERVAL=30
|
||||
REDIS_KEEPALIVE=true
|
||||
REDIS_KEEPALIVE_IDLE=30
|
||||
REDIS_KEEPALIVE_INTERVAL=10
|
||||
REDIS_KEEPALIVE_COUNT=10
|
||||
EVENT_BUS_REDIS_URL=
|
||||
EVENT_BUS_REDIS_CHANNEL_TYPE=pubsub
|
||||
EVENT_BUS_REDIS_USE_CLUSTERS=false
|
||||
BROKER_USE_SSL=false
|
||||
@@ -0,0 +1,7 @@
|
||||
# Defaults for certbot. Copy this file to certbot.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
CERTBOT_EMAIL=${CERTBOT_EMAIL:-}
|
||||
CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-}
|
||||
CERTBOT_OPTIONS=${CERTBOT_OPTIONS:-}
|
||||
@@ -1,7 +0,0 @@
|
||||
# ------------------------------
|
||||
# Certbot Configuration
|
||||
# ------------------------------
|
||||
|
||||
CERTBOT_EMAIL=your_email@example.com
|
||||
CERTBOT_DOMAIN=your_domain.com
|
||||
CERTBOT_OPTIONS=
|
||||
@@ -0,0 +1,8 @@
|
||||
# Defaults for etcd. Copy this file to etcd.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
ETCD_AUTO_COMPACTION_MODE=${ETCD_AUTO_COMPACTION_MODE:-revision}
|
||||
ETCD_AUTO_COMPACTION_RETENTION=${ETCD_AUTO_COMPACTION_RETENTION:-1000}
|
||||
ETCD_QUOTA_BACKEND_BYTES=${ETCD_QUOTA_BACKEND_BYTES:-4294967296}
|
||||
ETCD_SNAPSHOT_COUNT=${ETCD_SNAPSHOT_COUNT:-50000}
|
||||
@@ -1,4 +0,0 @@
|
||||
# ------------------------------
|
||||
# Etcd Configuration
|
||||
# ------------------------------
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Defaults for milvus-standalone. Copy this file to milvus-standalone.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
ETCD_ENDPOINTS=${ETCD_ENDPOINTS:-etcd:2379}
|
||||
MINIO_ADDRESS=${MINIO_ADDRESS:-minio:9000}
|
||||
MILVUS_AUTHORIZATION_ENABLED=${MILVUS_AUTHORIZATION_ENABLED:-true}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
common.security.authorizationEnabled=${MILVUS_AUTHORIZATION_ENABLED:-true}
|
||||
@@ -1,4 +0,0 @@
|
||||
# ------------------------------
|
||||
# Milvus Standalone Configuration
|
||||
# ------------------------------
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Defaults for minio. Copy this file to minio.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
MINIO_ACCESS_KEY=${MINIO_ACCESS_KEY:-minioadmin}
|
||||
MINIO_SECRET_KEY=${MINIO_SECRET_KEY:-minioadmin}
|
||||
@@ -1,4 +0,0 @@
|
||||
# ------------------------------
|
||||
# Minio Configuration
|
||||
# ------------------------------
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Defaults for nginx. Copy this file to nginx.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
NGINX_SERVER_NAME=${NGINX_SERVER_NAME:-_}
|
||||
# Supply certificates in docker/nginx/ssl or enable the Certbot challenge before enabling HTTPS.
|
||||
NGINX_HTTPS_ENABLED=${NGINX_HTTPS_ENABLED:-false}
|
||||
# Set NGINX_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# Set NGINX_SSL_PORT in docker/.env; Compose needs it before loading service files.
|
||||
NGINX_SSL_CERT_FILENAME=${NGINX_SSL_CERT_FILENAME:-dify.crt}
|
||||
NGINX_SSL_CERT_KEY_FILENAME=${NGINX_SSL_CERT_KEY_FILENAME:-dify.key}
|
||||
NGINX_SSL_PROTOCOLS=${NGINX_SSL_PROTOCOLS:-TLSv1.2 TLSv1.3}
|
||||
NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-auto}
|
||||
NGINX_CLIENT_MAX_BODY_SIZE=${NGINX_CLIENT_MAX_BODY_SIZE:-100M}
|
||||
NGINX_KEEPALIVE_TIMEOUT=${NGINX_KEEPALIVE_TIMEOUT:-65}
|
||||
NGINX_PROXY_READ_TIMEOUT=${NGINX_PROXY_READ_TIMEOUT:-3600s}
|
||||
NGINX_PROXY_SEND_TIMEOUT=${NGINX_PROXY_SEND_TIMEOUT:-3600s}
|
||||
NGINX_ENABLE_CERTBOT_CHALLENGE=${NGINX_ENABLE_CERTBOT_CHALLENGE:-false}
|
||||
NGINX_SOCKET_IO_UPSTREAM=${NGINX_SOCKET_IO_UPSTREAM:-api_websocket:5001}
|
||||
CERTBOT_DOMAIN=${CERTBOT_DOMAIN:-}
|
||||
@@ -1,18 +0,0 @@
|
||||
# ------------------------------
|
||||
# Nginx Configuration
|
||||
# ------------------------------
|
||||
|
||||
NGINX_SERVER_NAME=_
|
||||
NGINX_HTTPS_ENABLED=false
|
||||
NGINX_PORT=80
|
||||
NGINX_SSL_PORT=443
|
||||
NGINX_SSL_CERT_FILENAME=dify.crt
|
||||
NGINX_SSL_CERT_KEY_FILENAME=dify.key
|
||||
NGINX_SSL_PROTOCOLS=TLSv1.2 TLSv1.3
|
||||
NGINX_WORKER_PROCESSES=auto
|
||||
NGINX_CLIENT_MAX_BODY_SIZE=100M
|
||||
NGINX_KEEPALIVE_TIMEOUT=65
|
||||
NGINX_PROXY_READ_TIMEOUT=3600s
|
||||
NGINX_PROXY_SEND_TIMEOUT=3600s
|
||||
NGINX_ENABLE_CERTBOT_CHALLENGE=false
|
||||
NGINX_SOCKET_IO_UPSTREAM=api_websocket:5001
|
||||
@@ -0,0 +1,30 @@
|
||||
# Defaults for ssrf_proxy. Copy this file to ssrf-proxy.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# SSRF_PROXY_HTTP_URL=http://ssrf_proxy:3128
|
||||
# SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128
|
||||
SSRF_HTTP_PORT=${SSRF_HTTP_PORT:-3128}
|
||||
SSRF_COREDUMP_DIR=${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
# Comma-separated CIDR ranges that the SSRF proxy should allow even when they
|
||||
# resolve to private, loopback, link-local, or otherwise non-public addresses.
|
||||
# Leave empty (the default) to keep the deny-by-default policy. Required when
|
||||
# Dify needs to reach internal HTTP endpoints (e.g. an internal API on
|
||||
# http://172.21.x.x) from an HTTP Request node, a tool, or a plugin.
|
||||
# Example: 172.21.0.0/16,10.0.0.0/8
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS=${SSRF_PROXY_ALLOW_PRIVATE_IPS:-}
|
||||
# Comma-separated domain suffixes that the SSRF proxy should allow even when
|
||||
# they would otherwise resolve to a denied range. Leave empty to keep the
|
||||
# deny-by-default policy.
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS=${SSRF_PROXY_ALLOW_PRIVATE_DOMAINS:-}
|
||||
# SSRF_DEFAULT_TIME_OUT=5
|
||||
# SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||
# SSRF_DEFAULT_READ_TIME_OUT=5
|
||||
# SSRF_DEFAULT_WRITE_TIME_OUT=5
|
||||
# SSRF_POOL_MAX_CONNECTIONS=100
|
||||
# SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
# SSRF_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
COREDUMP_DIR=${SSRF_COREDUMP_DIR:-/var/spool/squid}
|
||||
HTTP_PORT=${SSRF_HTTP_PORT:-3128}
|
||||
@@ -1,26 +0,0 @@
|
||||
# ------------------------------
|
||||
# Ssrf Proxy Configuration
|
||||
# ------------------------------
|
||||
|
||||
SSRF_PROXY_HTTP_URL=http://ssrf_proxy:3128
|
||||
SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128
|
||||
SSRF_HTTP_PORT=3128
|
||||
SSRF_COREDUMP_DIR=/var/spool/squid
|
||||
# Comma-separated CIDR ranges that the SSRF proxy should allow even when they
|
||||
# resolve to private, loopback, link-local, or otherwise non-public addresses.
|
||||
# Leave empty (the default) to keep the deny-by-default policy. Required when
|
||||
# Dify needs to reach internal HTTP endpoints (e.g. an internal API on
|
||||
# http://172.21.x.x) from an HTTP Request node, a tool, or a plugin.
|
||||
# Example: 172.21.0.0/16,10.0.0.0/8
|
||||
SSRF_PROXY_ALLOW_PRIVATE_IPS=
|
||||
# Comma-separated domain suffixes that the SSRF proxy should allow even when
|
||||
# they would otherwise resolve to a denied range. Leave empty to keep the
|
||||
# deny-by-default policy.
|
||||
SSRF_PROXY_ALLOW_PRIVATE_DOMAINS=
|
||||
SSRF_DEFAULT_TIME_OUT=5
|
||||
SSRF_DEFAULT_CONNECT_TIME_OUT=5
|
||||
SSRF_DEFAULT_READ_TIME_OUT=5
|
||||
SSRF_DEFAULT_WRITE_TIME_OUT=5
|
||||
SSRF_POOL_MAX_CONNECTIONS=100
|
||||
SSRF_POOL_MAX_KEEPALIVE_CONNECTIONS=20
|
||||
SSRF_POOL_KEEPALIVE_EXPIRY=5.0
|
||||
@@ -0,0 +1,16 @@
|
||||
# Defaults for chroma. Copy this file to chroma.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# CHROMA_DATABASE=default_database
|
||||
# CHROMA_AUTH_PROVIDER=chromadb.auth.token_authn.TokenAuthClientProvider
|
||||
# CHROMA_AUTH_CREDENTIALS=
|
||||
# CHROMA_HOST=127.0.0.1
|
||||
# CHROMA_PORT=8000
|
||||
# CHROMA_TENANT=default_tenant
|
||||
CHROMA_SERVER_AUTHN_CREDENTIALS=${CHROMA_SERVER_AUTHN_CREDENTIALS:-difyai123456}
|
||||
CHROMA_SERVER_AUTHN_PROVIDER=${CHROMA_SERVER_AUTHN_PROVIDER:-chromadb.auth.token_authn.TokenAuthenticationServerProvider}
|
||||
CHROMA_IS_PERSISTENT=${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
IS_PERSISTENT=${CHROMA_IS_PERSISTENT:-TRUE}
|
||||
@@ -1,13 +0,0 @@
|
||||
# ------------------------------
|
||||
# Chroma Configuration
|
||||
# ------------------------------
|
||||
|
||||
CHROMA_DATABASE=default_database
|
||||
CHROMA_AUTH_PROVIDER=chromadb.auth.token_authn.TokenAuthClientProvider
|
||||
CHROMA_AUTH_CREDENTIALS=
|
||||
CHROMA_HOST=127.0.0.1
|
||||
CHROMA_PORT=8000
|
||||
CHROMA_TENANT=default_tenant
|
||||
CHROMA_SERVER_AUTHN_CREDENTIALS=difyai123456
|
||||
CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider
|
||||
CHROMA_IS_PERSISTENT=TRUE
|
||||
@@ -0,0 +1,14 @@
|
||||
# Defaults for couchbase-server. Copy this file to couchbase.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
COUCHBASE_PASSWORD=${COUCHBASE_PASSWORD:-password}
|
||||
COUCHBASE_BUCKET_NAME=${COUCHBASE_BUCKET_NAME:-Embeddings}
|
||||
# COUCHBASE_SCOPE_NAME=_default
|
||||
# COUCHBASE_CONNECTION_STRING=couchbase://couchbase-server
|
||||
COUCHBASE_USER=${COUCHBASE_USER:-Administrator}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
COUCHBASE_ADMINISTRATOR_USERNAME=${COUCHBASE_USER:-Administrator}
|
||||
COUCHBASE_ADMINISTRATOR_PASSWORD=${COUCHBASE_PASSWORD:-password}
|
||||
COUCHBASE_BUCKET=${COUCHBASE_BUCKET_NAME:-Embeddings}
|
||||
@@ -1,9 +0,0 @@
|
||||
# ------------------------------
|
||||
# Couchbase Configuration
|
||||
# ------------------------------
|
||||
|
||||
COUCHBASE_PASSWORD=password
|
||||
COUCHBASE_BUCKET_NAME=Embeddings
|
||||
COUCHBASE_SCOPE_NAME=_default
|
||||
COUCHBASE_CONNECTION_STRING=couchbase://couchbase-server
|
||||
COUCHBASE_USER=Administrator
|
||||
@@ -0,0 +1,21 @@
|
||||
# Defaults for elasticsearch. Copy this file to elasticsearch.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# ELASTICSEARCH_CLOUD_URL=YOUR-ELASTICSEARCH_CLOUD_URL
|
||||
ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD:-elastic}
|
||||
# Set KIBANA_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# ELASTICSEARCH_USE_CLOUD=false
|
||||
# ELASTICSEARCH_API_KEY=YOUR-ELASTICSEARCH_API_KEY
|
||||
# ELASTICSEARCH_VERIFY_CERTS=False
|
||||
# ELASTICSEARCH_CA_CERTS=
|
||||
# ELASTICSEARCH_REQUEST_TIMEOUT=100000
|
||||
# ELASTICSEARCH_RETRY_ON_TIMEOUT=True
|
||||
# ELASTICSEARCH_MAX_RETRIES=10
|
||||
# ELASTICSEARCH_HOST=0.0.0.0
|
||||
# Set ELASTICSEARCH_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# ELASTICSEARCH_USERNAME=elastic
|
||||
# Set VECTOR_STORE in docker/.env to select the backend and its Compose profile together.
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
ELASTIC_PASSWORD=${ELASTICSEARCH_PASSWORD:-elastic}
|
||||
@@ -1,17 +0,0 @@
|
||||
# ------------------------------
|
||||
# Elasticsearch Configuration
|
||||
# ------------------------------
|
||||
|
||||
ELASTICSEARCH_CLOUD_URL=YOUR-ELASTICSEARCH_CLOUD_URL
|
||||
ELASTICSEARCH_PASSWORD=elastic
|
||||
KIBANA_PORT=5601
|
||||
ELASTICSEARCH_USE_CLOUD=false
|
||||
ELASTICSEARCH_API_KEY=YOUR-ELASTICSEARCH_API_KEY
|
||||
ELASTICSEARCH_VERIFY_CERTS=False
|
||||
ELASTICSEARCH_CA_CERTS=
|
||||
ELASTICSEARCH_REQUEST_TIMEOUT=100000
|
||||
ELASTICSEARCH_RETRY_ON_TIMEOUT=True
|
||||
ELASTICSEARCH_MAX_RETRIES=10
|
||||
ELASTICSEARCH_HOST=0.0.0.0
|
||||
ELASTICSEARCH_PORT=9200
|
||||
ELASTICSEARCH_USERNAME=elastic
|
||||
@@ -0,0 +1,20 @@
|
||||
# Defaults for iris. Copy this file to iris.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# IRIS_CONNECTION_URL=
|
||||
# IRIS_MIN_CONNECTION=1
|
||||
# IRIS_MAX_CONNECTION=3
|
||||
# IRIS_TEXT_INDEX=true
|
||||
# IRIS_TEXT_INDEX_LANGUAGE=en
|
||||
IRIS_TIMEZONE=${IRIS_TIMEZONE:-UTC}
|
||||
# IRIS_PASSWORD=Dify@1234
|
||||
# IRIS_DATABASE=USER
|
||||
# IRIS_SCHEMA=dify
|
||||
# IRIS_HOST=iris
|
||||
# Set IRIS_SUPER_SERVER_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# Set IRIS_WEB_SERVER_PORT in docker/.env; Compose needs it before loading service files.
|
||||
# IRIS_USER=_SYSTEM
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
TZ=${IRIS_TIMEZONE:-UTC}
|
||||
@@ -1,17 +0,0 @@
|
||||
# ------------------------------
|
||||
# Iris Configuration
|
||||
# ------------------------------
|
||||
|
||||
IRIS_CONNECTION_URL=
|
||||
IRIS_MIN_CONNECTION=1
|
||||
IRIS_MAX_CONNECTION=3
|
||||
IRIS_TEXT_INDEX=true
|
||||
IRIS_TEXT_INDEX_LANGUAGE=en
|
||||
IRIS_TIMEZONE=UTC
|
||||
IRIS_PASSWORD=Dify@1234
|
||||
IRIS_DATABASE=USER
|
||||
IRIS_SCHEMA=dify
|
||||
IRIS_HOST=iris
|
||||
IRIS_SUPER_SERVER_PORT=1972
|
||||
IRIS_WEB_SERVER_PORT=52773
|
||||
IRIS_USER=_SYSTEM
|
||||
@@ -14,3 +14,12 @@ MILVUS_AUTHORIZATION_ENABLED=true
|
||||
MILVUS_SECURE=false
|
||||
MILVUS_SERVER_PEM_PATH=
|
||||
MILVUS_SERVER_NAME=
|
||||
|
||||
# Dify vector client settings (API, workers and Beat)
|
||||
# MILVUS_URI=http://host.docker.internal:19530
|
||||
# MILVUS_TOKEN=
|
||||
# MILVUS_USER=
|
||||
# MILVUS_PASSWORD=
|
||||
# MILVUS_ANALYZER_PARAMS=
|
||||
# MILVUS_DATABASE=
|
||||
# MILVUS_ENABLE_HYBRID_SEARCH=False
|
||||
@@ -0,0 +1,21 @@
|
||||
# Defaults for oceanbase. Copy this file to oceanbase.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
OCEANBASE_CLUSTER_NAME=${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OCEANBASE_MEMORY_LIMIT=${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OCEANBASE_VECTOR_PASSWORD=${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
|
||||
# Dify vector client settings (API, workers and Beat)
|
||||
# Set OCEANBASE_VECTOR_PORT in docker/.env to keep the client and published port aligned.
|
||||
# OCEANBASE_VECTOR_HOST=oceanbase
|
||||
# OCEANBASE_VECTOR_USER=root@test
|
||||
# OCEANBASE_VECTOR_DATABASE=test
|
||||
# OCEANBASE_ENABLE_HYBRID_SEARCH=false
|
||||
# OCEANBASE_FULLTEXT_PARSER=ik
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
OB_CLUSTER_NAME=${OCEANBASE_CLUSTER_NAME:-difyai}
|
||||
OB_MEMORY_LIMIT=${OCEANBASE_MEMORY_LIMIT:-6G}
|
||||
OB_SYS_PASSWORD=${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
OB_TENANT_PASSWORD=${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
@@ -1,6 +0,0 @@
|
||||
# ------------------------------
|
||||
# Oceanbase Configuration
|
||||
# ------------------------------
|
||||
|
||||
OCEANBASE_CLUSTER_NAME=difyai
|
||||
OCEANBASE_MEMORY_LIMIT=6G
|
||||
@@ -0,0 +1,17 @@
|
||||
# Defaults for opengauss. Copy this file to opengauss.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
OPENGAUSS_PASSWORD=${OPENGAUSS_PASSWORD:-Dify@123}
|
||||
OPENGAUSS_DATABASE=${OPENGAUSS_DATABASE:-dify}
|
||||
# OPENGAUSS_MIN_CONNECTION=1
|
||||
# OPENGAUSS_MAX_CONNECTION=5
|
||||
# OPENGAUSS_ENABLE_PQ=false
|
||||
# OPENGAUSS_HOST=opengauss
|
||||
# Set OPENGAUSS_PORT in docker/.env; Compose needs it before loading service files.
|
||||
OPENGAUSS_USER=${OPENGAUSS_USER:-postgres}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
GS_DB=${OPENGAUSS_DATABASE:-dify}
|
||||
GS_PASSWORD=${OPENGAUSS_PASSWORD:-Dify@123}
|
||||
GS_USERNAME=${OPENGAUSS_USER:-postgres}
|
||||
@@ -1,12 +0,0 @@
|
||||
# ------------------------------
|
||||
# Opengauss Configuration
|
||||
# ------------------------------
|
||||
|
||||
OPENGAUSS_PASSWORD=Dify@123
|
||||
OPENGAUSS_DATABASE=dify
|
||||
OPENGAUSS_MIN_CONNECTION=1
|
||||
OPENGAUSS_MAX_CONNECTION=5
|
||||
OPENGAUSS_ENABLE_PQ=false
|
||||
OPENGAUSS_HOST=opengauss
|
||||
OPENGAUSS_PORT=6600
|
||||
OPENGAUSS_USER=postgres
|
||||
@@ -0,0 +1,27 @@
|
||||
# Defaults for opensearch. Copy this file to opensearch.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# OPENSEARCH_PASSWORD=admin
|
||||
# OPENSEARCH_AWS_REGION=ap-southeast-1
|
||||
# OPENSEARCH_AWS_SERVICE=aoss
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD:-Qazwsxedc!@#123}
|
||||
# Set OPENSEARCH_MEMLOCK_SOFT in docker/.env; Compose needs it before loading service files.
|
||||
# Set OPENSEARCH_MEMLOCK_HARD in docker/.env; Compose needs it before loading service files.
|
||||
# Set OPENSEARCH_NOFILE_SOFT in docker/.env; Compose needs it before loading service files.
|
||||
# Set OPENSEARCH_NOFILE_HARD in docker/.env; Compose needs it before loading service files.
|
||||
# OPENSEARCH_HOST=opensearch
|
||||
# OPENSEARCH_PORT=9200
|
||||
# OPENSEARCH_SECURE=true
|
||||
# OPENSEARCH_VERIFY_CERTS=true
|
||||
# OPENSEARCH_AUTH_METHOD=basic
|
||||
# OPENSEARCH_USER=admin
|
||||
OPENSEARCH_DISCOVERY_TYPE=${OPENSEARCH_DISCOVERY_TYPE:-single-node}
|
||||
OPENSEARCH_BOOTSTRAP_MEMORY_LOCK=${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true}
|
||||
OPENSEARCH_JAVA_OPTS_MIN=${OPENSEARCH_JAVA_OPTS_MIN:-512m}
|
||||
OPENSEARCH_JAVA_OPTS_MAX=${OPENSEARCH_JAVA_OPTS_MAX:-1024m}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
OPENSEARCH_JAVA_OPTS=-Xms${OPENSEARCH_JAVA_OPTS_MIN:-512m} -Xmx${OPENSEARCH_JAVA_OPTS_MAX:-1024m}
|
||||
bootstrap.memory_lock=${OPENSEARCH_BOOTSTRAP_MEMORY_LOCK:-true}
|
||||
discovery.type=${OPENSEARCH_DISCOVERY_TYPE:-single-node}
|
||||
@@ -1,22 +0,0 @@
|
||||
# ------------------------------
|
||||
# Opensearch Configuration
|
||||
# ------------------------------
|
||||
|
||||
OPENSEARCH_PASSWORD=admin
|
||||
OPENSEARCH_AWS_REGION=ap-southeast-1
|
||||
OPENSEARCH_AWS_SERVICE=aoss
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD=Qazwsxedc!@#123
|
||||
OPENSEARCH_MEMLOCK_SOFT=-1
|
||||
OPENSEARCH_MEMLOCK_HARD=-1
|
||||
OPENSEARCH_NOFILE_SOFT=65536
|
||||
OPENSEARCH_NOFILE_HARD=65536
|
||||
OPENSEARCH_HOST=opensearch
|
||||
OPENSEARCH_PORT=9200
|
||||
OPENSEARCH_SECURE=true
|
||||
OPENSEARCH_VERIFY_CERTS=true
|
||||
OPENSEARCH_AUTH_METHOD=basic
|
||||
OPENSEARCH_USER=admin
|
||||
OPENSEARCH_DISCOVERY_TYPE=single-node
|
||||
OPENSEARCH_BOOTSTRAP_MEMORY_LOCK=true
|
||||
OPENSEARCH_JAVA_OPTS_MIN=512m
|
||||
OPENSEARCH_JAVA_OPTS_MAX=1024m
|
||||
@@ -0,0 +1,13 @@
|
||||
# Defaults for oracle. Copy this file to oracle.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# ORACLE_PASSWORD=dify
|
||||
# ORACLE_DSN=oracle:1521/FREEPDB1
|
||||
# ORACLE_CONFIG_DIR=/app/api/storage/wallet
|
||||
# ORACLE_WALLET_LOCATION=/app/api/storage/wallet
|
||||
# ORACLE_WALLET_PASSWORD=dify
|
||||
# ORACLE_IS_AUTONOMOUS=false
|
||||
# ORACLE_USER=dify
|
||||
ORACLE_PWD=${ORACLE_PWD:-Dify123456}
|
||||
ORACLE_CHARACTERSET=${ORACLE_CHARACTERSET:-AL32UTF8}
|
||||
@@ -1,13 +0,0 @@
|
||||
# ------------------------------
|
||||
# Oracle Configuration
|
||||
# ------------------------------
|
||||
|
||||
ORACLE_PASSWORD=dify
|
||||
ORACLE_DSN=oracle:1521/FREEPDB1
|
||||
ORACLE_CONFIG_DIR=/app/api/storage/wallet
|
||||
ORACLE_WALLET_LOCATION=/app/api/storage/wallet
|
||||
ORACLE_WALLET_PASSWORD=dify
|
||||
ORACLE_IS_AUTONOMOUS=false
|
||||
ORACLE_USER=dify
|
||||
ORACLE_PWD=Dify123456
|
||||
ORACLE_CHARACTERSET=AL32UTF8
|
||||
@@ -0,0 +1,19 @@
|
||||
# Defaults for pgvecto-rs. Copy this file to pgvecto-rs.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
# PGVECTO_RS_HOST=pgvecto-rs
|
||||
# PGVECTO_RS_PORT=5432
|
||||
# PGVECTO_RS_USER=postgres
|
||||
# PGVECTO_RS_PASSWORD=difyai123456
|
||||
# PGVECTO_RS_DATABASE=dify
|
||||
PGVECTOR_PGDATA=${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
PGVECTOR_PGUSER=${PGVECTOR_PGUSER:-postgres}
|
||||
PGVECTOR_POSTGRES_DB=${PGVECTOR_POSTGRES_DB:-dify}
|
||||
PGVECTOR_POSTGRES_PASSWORD=${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
PGDATA=${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
PGUSER=${PGVECTOR_PGUSER:-postgres}
|
||||
POSTGRES_DB=${PGVECTOR_POSTGRES_DB:-dify}
|
||||
POSTGRES_PASSWORD=${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
@@ -1,9 +0,0 @@
|
||||
# ------------------------------
|
||||
# Pgvecto Rs Configuration
|
||||
# ------------------------------
|
||||
|
||||
PGVECTO_RS_HOST=pgvecto-rs
|
||||
PGVECTO_RS_PORT=5432
|
||||
PGVECTO_RS_USER=postgres
|
||||
PGVECTO_RS_PASSWORD=difyai123456
|
||||
PGVECTO_RS_DATABASE=dify
|
||||
@@ -0,0 +1,27 @@
|
||||
# Defaults for pgvector. Copy this file to pgvector.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
PGVECTOR_PGUSER=${PGVECTOR_PGUSER:-postgres}
|
||||
PGVECTOR_POSTGRES_PASSWORD=${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
PGVECTOR_POSTGRES_DB=${PGVECTOR_POSTGRES_DB:-dify}
|
||||
PGVECTOR_PGDATA=${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
PGVECTOR_PG_BIGM=${PGVECTOR_PG_BIGM:-false}
|
||||
PGVECTOR_PG_BIGM_VERSION=${PGVECTOR_PG_BIGM_VERSION:-1.2-20240606}
|
||||
|
||||
# Dify vector client settings (API, workers and Beat)
|
||||
# PGVECTOR_HOST=pgvector
|
||||
# PGVECTOR_PORT=5432
|
||||
# PGVECTOR_USER=postgres
|
||||
# PGVECTOR_PASSWORD=difyai123456
|
||||
# PGVECTOR_DATABASE=dify
|
||||
# PGVECTOR_MIN_CONNECTION=1
|
||||
# PGVECTOR_MAX_CONNECTION=5
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
PGDATA=${PGVECTOR_PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
PGUSER=${PGVECTOR_PGUSER:-postgres}
|
||||
PG_BIGM=${PGVECTOR_PG_BIGM:-false}
|
||||
PG_BIGM_VERSION=${PGVECTOR_PG_BIGM_VERSION:-1.2-20240606}
|
||||
POSTGRES_DB=${PGVECTOR_POSTGRES_DB:-dify}
|
||||
POSTGRES_PASSWORD=${PGVECTOR_POSTGRES_PASSWORD:-difyai123456}
|
||||
@@ -1,8 +0,0 @@
|
||||
# ------------------------------
|
||||
# Pgvector Configuration
|
||||
# ------------------------------
|
||||
|
||||
PGVECTOR_PGUSER=postgres
|
||||
PGVECTOR_POSTGRES_PASSWORD=difyai123456
|
||||
PGVECTOR_POSTGRES_DB=dify
|
||||
PGVECTOR_PGDATA=/var/lib/postgresql/data/pgdata
|
||||
@@ -0,0 +1,12 @@
|
||||
# Defaults for qdrant. Copy this file to qdrant.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
QDRANT_API_KEY=${QDRANT_API_KEY:-difyai123456}
|
||||
|
||||
# Dify vector client settings (API, workers and Beat)
|
||||
# QDRANT_URL=http://qdrant:6333
|
||||
# QDRANT_CLIENT_TIMEOUT=20
|
||||
# QDRANT_GRPC_ENABLED=false
|
||||
# QDRANT_GRPC_PORT=6334
|
||||
# QDRANT_REPLICATION_FACTOR=1
|
||||
@@ -1,4 +0,0 @@
|
||||
# ------------------------------
|
||||
# Qdrant Configuration
|
||||
# ------------------------------
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Defaults for seekdb. Copy this file to seekdb.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
SEEKDB_MEMORY_LIMIT=${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
OCEANBASE_VECTOR_PASSWORD=${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
MEMORY_LIMIT=${SEEKDB_MEMORY_LIMIT:-2G}
|
||||
ROOT_PASSWORD=${OCEANBASE_VECTOR_PASSWORD:-difyai123456}
|
||||
@@ -1,4 +0,0 @@
|
||||
# ------------------------------
|
||||
# Seekdb Configuration
|
||||
# ------------------------------
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Defaults for weaviate. Copy this file to weaviate.env to customize it.
|
||||
# Edit the settings below in the copy; docker/.env takes precedence.
|
||||
# Optional application settings are commented to retain their application defaults.
|
||||
|
||||
WEAVIATE_PERSISTENCE_DATA_PATH=${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate}
|
||||
WEAVIATE_QUERY_DEFAULTS_LIMIT=${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25}
|
||||
WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-true}
|
||||
WEAVIATE_DEFAULT_VECTORIZER_MODULE=${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none}
|
||||
WEAVIATE_CLUSTER_HOSTNAME=${WEAVIATE_CLUSTER_HOSTNAME:-node1}
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_ENABLED=${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true}
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=${WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
WEAVIATE_DISABLE_TELEMETRY=${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_GSE=${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA=${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR=${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
|
||||
# Dify vector client settings (API, workers and Beat)
|
||||
# WEAVIATE_TOKENIZATION=word
|
||||
|
||||
# Container variable mappings; keep these expressions unchanged in the copy.
|
||||
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-true}
|
||||
AUTHENTICATION_APIKEY_ALLOWED_KEYS=${WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
|
||||
AUTHENTICATION_APIKEY_ENABLED=${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true}
|
||||
AUTHENTICATION_APIKEY_USERS=${WEAVIATE_AUTHENTICATION_APIKEY_USERS:-hello@dify.ai}
|
||||
AUTHORIZATION_ADMINLIST_ENABLED=${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true}
|
||||
AUTHORIZATION_ADMINLIST_USERS=${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai}
|
||||
CLUSTER_HOSTNAME=${WEAVIATE_CLUSTER_HOSTNAME:-node1}
|
||||
DEFAULT_VECTORIZER_MODULE=${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none}
|
||||
DISABLE_TELEMETRY=${WEAVIATE_DISABLE_TELEMETRY:-false}
|
||||
ENABLE_TOKENIZER_GSE=${WEAVIATE_ENABLE_TOKENIZER_GSE:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_JA=${WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA:-false}
|
||||
ENABLE_TOKENIZER_KAGOME_KR=${WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR:-false}
|
||||
PERSISTENCE_DATA_PATH=${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate}
|
||||
QUERY_DEFAULTS_LIMIT=${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25}
|
||||
@@ -1,18 +0,0 @@
|
||||
# ------------------------------
|
||||
# Weaviate Configuration
|
||||
# ------------------------------
|
||||
|
||||
WEAVIATE_PERSISTENCE_DATA_PATH=/var/lib/weaviate
|
||||
WEAVIATE_QUERY_DEFAULTS_LIMIT=25
|
||||
WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true
|
||||
WEAVIATE_DEFAULT_VECTORIZER_MODULE=none
|
||||
WEAVIATE_CLUSTER_HOSTNAME=node1
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_ENABLED=true
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
|
||||
WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true
|
||||
WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai
|
||||
WEAVIATE_DISABLE_TELEMETRY=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_GSE=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_JA=false
|
||||
WEAVIATE_ENABLE_TOKENIZER_KAGOME_KR=false
|
||||
@@ -64,50 +64,20 @@ def generate_shared_env_block(env_vars, anchor_name="shared-api-worker-env"):
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def create_env_files_from_example(env_example_path):
|
||||
"""
|
||||
Creates actual env files from .env.example by copying the categorized .env.example files.
|
||||
This allows docker-compose to use env_file references.
|
||||
Supports per-module structure with subdirectories.
|
||||
"""
|
||||
def create_env_file_from_example(env_example_path):
|
||||
"""Create the required root .env without activating optional provider settings."""
|
||||
base_dir = os.path.dirname(os.path.abspath(env_example_path))
|
||||
root_env_file = os.path.join(base_dir, ".env")
|
||||
if not os.path.exists(root_env_file):
|
||||
with open(env_example_path, "r", encoding="utf-8") as src, open(
|
||||
root_env_file, "w", encoding="utf-8", newline="\n"
|
||||
) as dst:
|
||||
with (
|
||||
open(env_example_path, "r", encoding="utf-8") as src,
|
||||
open(root_env_file, "w", encoding="utf-8", newline="\n") as dst,
|
||||
):
|
||||
dst.write(src.read())
|
||||
print(f"Created {root_env_file}")
|
||||
else:
|
||||
print(f"{root_env_file} already exists, skipping")
|
||||
|
||||
envs_dir = os.path.join(base_dir, "envs")
|
||||
if not os.path.isdir(envs_dir):
|
||||
print(f"No envs directory found at {envs_dir}, skipping split env files")
|
||||
return []
|
||||
|
||||
created_files = []
|
||||
# Walk through all .env.example files in subdirectories
|
||||
for root, dirs, files in os.walk(envs_dir):
|
||||
for file in files:
|
||||
if file.endswith('.env.example'):
|
||||
example_file = os.path.join(root, file)
|
||||
env_file = example_file.replace('.env.example', '.env')
|
||||
|
||||
if os.path.exists(env_file):
|
||||
print(f"{env_file} already exists, skipping")
|
||||
continue
|
||||
|
||||
# Copy .example to actual file
|
||||
with open(example_file, "r", encoding="utf-8") as src, open(
|
||||
env_file, "w", encoding="utf-8", newline="\n"
|
||||
) as dst:
|
||||
dst.write(src.read())
|
||||
created_files.append(env_file)
|
||||
print(f"Created {env_file}")
|
||||
|
||||
return created_files
|
||||
|
||||
|
||||
def insert_shared_env(template_path, output_path, header_comments):
|
||||
"""
|
||||
@@ -146,11 +116,8 @@ def main():
|
||||
print(f"Error: File {path} does not exist.")
|
||||
sys.exit(1)
|
||||
|
||||
# Create env files from categorized .env.example files
|
||||
# These files are used by docker-compose's env_file directive
|
||||
# This ensures .env files exist even in CI/CD environments
|
||||
if "--compose-only" not in sys.argv:
|
||||
create_env_files_from_example(env_example_path)
|
||||
create_env_file_from_example(env_example_path)
|
||||
|
||||
# Copy template to output with header comments
|
||||
# The template now uses env_file references instead of a huge YAML anchor
|
||||
|
||||
@@ -0,0 +1,573 @@
|
||||
"""Exercise copied Docker defaults without starting containers."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
DOCKER_DIR = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class ComposeEnvironmentTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory(prefix="dify-compose-env-")
|
||||
self.addCleanup(self.temp.cleanup)
|
||||
self.project = Path(self.temp.name)
|
||||
shutil.copyfile(DOCKER_DIR / "docker-compose.yaml", self.project / "docker-compose.yaml")
|
||||
for source in (DOCKER_DIR / "envs").rglob("*.defaults"):
|
||||
target = self.project / source.relative_to(DOCKER_DIR)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(source, target)
|
||||
self.copy_template(
|
||||
".env.example",
|
||||
".env",
|
||||
{"DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN": "test-sandbox-token"},
|
||||
)
|
||||
|
||||
def copy_template(self, source, target, values=None):
|
||||
content = (DOCKER_DIR / source).read_text()
|
||||
for key, value in (values or {}).items():
|
||||
content, count = re.subn(
|
||||
rf"(?m)^(?:#\s*)?{re.escape(key)}=.*$",
|
||||
lambda _, setting=f"{key}={value}": setting,
|
||||
content,
|
||||
)
|
||||
self.assertEqual(count, 1, f"Expected one setting for {key} in {source}")
|
||||
destination = self.project / target
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
destination.write_text(content)
|
||||
|
||||
def override_root(self, values):
|
||||
with (self.project / ".env").open("a") as target:
|
||||
target.write("\n" + "\n".join(f"{key}={value}" for key, value in values.items()) + "\n")
|
||||
|
||||
def render(self, *compose_args):
|
||||
inputs = set(re.findall(r"\$\{(\w+)", (DOCKER_DIR / "docker-compose.yaml").read_text()))
|
||||
for source in (DOCKER_DIR / "envs").rglob("*.defaults"):
|
||||
inputs.update(re.findall(r"\$\{(\w+)", source.read_text()))
|
||||
env = {key: value for key, value in os.environ.items() if key not in inputs and not key.startswith("COMPOSE_")}
|
||||
result = subprocess.run(
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
*compose_args,
|
||||
"--profile",
|
||||
"*",
|
||||
"config",
|
||||
"--format",
|
||||
"json",
|
||||
],
|
||||
cwd=self.project,
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
return json.loads(result.stdout)["services"]
|
||||
|
||||
def test_minimal_setup_has_working_connection_defaults(self):
|
||||
services = self.render()
|
||||
for name in ("api", "worker", "worker_beat", "plugin_daemon"):
|
||||
values = services[name]["environment"]
|
||||
for key, expected in {
|
||||
"DB_HOST": "db_postgres",
|
||||
"DB_USERNAME": "postgres",
|
||||
"DB_PASSWORD": "difyai123456",
|
||||
"DB_PORT": "5432",
|
||||
"REDIS_HOST": "redis",
|
||||
"REDIS_PORT": "6379",
|
||||
"REDIS_PASSWORD": "difyai123456",
|
||||
}.items():
|
||||
self.assertEqual(values[key], expected, f"{name}.{key}")
|
||||
self.assertEqual(services["plugin_daemon"]["environment"]["DB_DATABASE"], "dify_plugin")
|
||||
self.assertEqual(services["web"]["environment"]["SERVER_CONSOLE_API_URL"], "http://api:5001")
|
||||
self.assertEqual(services["web"]["environment"]["NEXT_PUBLIC_ENABLE_AGENT_V2"], "true")
|
||||
self.assertEqual(
|
||||
services["local_sandbox"]["environment"]["SHELLCTL_AUTH_TOKEN"],
|
||||
"test-sandbox-token",
|
||||
)
|
||||
self.assertEqual(
|
||||
services["agent_backend"]["environment"]["DIFY_AGENT_LOCAL_SANDBOX_AUTH_TOKEN"],
|
||||
"test-sandbox-token",
|
||||
)
|
||||
self.assertFalse((DOCKER_DIR / ".env.custom.example").exists())
|
||||
self.assertEqual(services["elasticsearch"]["environment"]["xpack.security.enabled"], "true")
|
||||
self.assertEqual(services["elasticsearch"]["environment"]["discovery.type"], "single-node")
|
||||
|
||||
def test_copying_defaults_without_changes_preserves_service_values(self):
|
||||
baseline = self.render()
|
||||
for source in (DOCKER_DIR / "envs").rglob("*.defaults"):
|
||||
# This KnowledgeFS parser file deliberately has a different override basename.
|
||||
if source.name == "knowledge-fs-unstructured-service.defaults":
|
||||
continue
|
||||
self.copy_template(
|
||||
str(source.relative_to(DOCKER_DIR)),
|
||||
str(source.relative_to(DOCKER_DIR).with_suffix(".env")),
|
||||
)
|
||||
actual = self.render()
|
||||
for name, service in baseline.items():
|
||||
for key, value in service.get("environment", {}).items():
|
||||
self.assertEqual(actual[name]["environment"].get(key), value, f"{name}.{key}")
|
||||
|
||||
def test_api_and_weaviate_defaults_and_isolated_overrides(self):
|
||||
cases = [
|
||||
("core-services/shared", "worker", "CELERY_WORKER_AMOUNT", "CELERY_WORKER_AMOUNT", "4", "2", "3"),
|
||||
("core-services/shared", "api", "SERVER_WORKER_CLASS", "SERVER_WORKER_CLASS", "gevent", "sync", "gthread"),
|
||||
("core-services/shared", "api", "GUNICORN_TIMEOUT", "GUNICORN_TIMEOUT", "360", "120", "240"),
|
||||
(
|
||||
"vectorstores/weaviate",
|
||||
"weaviate",
|
||||
"WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED",
|
||||
"AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED",
|
||||
"true",
|
||||
"false",
|
||||
"true",
|
||||
),
|
||||
]
|
||||
root = self.project / ".env"
|
||||
initial_root = root.read_text()
|
||||
for path, service, key, native, default, custom, root_value in cases:
|
||||
with self.subTest(setting=key):
|
||||
source = f"envs/{path}.defaults"
|
||||
target = f"envs/{path}.env"
|
||||
try:
|
||||
self.assertEqual(self.render()[service]["environment"].get(native), default, "fresh deployment")
|
||||
|
||||
# Exercise root customization without any service override file.
|
||||
self.override_root({key: custom})
|
||||
self.assertEqual(self.render()[service]["environment"][native], custom, "root only")
|
||||
root.write_text(initial_root)
|
||||
self.assertEqual(self.render()[service]["environment"][native], default, "restored root")
|
||||
|
||||
self.copy_template(source, target)
|
||||
self.assertEqual(self.render()[service]["environment"][native], default, "unchanged copy")
|
||||
self.copy_template(source, target, {key: custom})
|
||||
self.assertEqual(self.render()[service]["environment"][native], custom, "service only")
|
||||
|
||||
# Leave the service file unchanged while changing only the root file.
|
||||
self.override_root({key: root_value})
|
||||
self.assertEqual(self.render()[service]["environment"][native], root_value, "root precedence")
|
||||
finally:
|
||||
(self.project / target).unlink(missing_ok=True)
|
||||
root.write_text(initial_root)
|
||||
|
||||
def test_copying_shared_defaults_does_not_activate_optional_settings(self):
|
||||
baseline = self.render()
|
||||
self.copy_template("envs/core-services/shared.defaults", "envs/core-services/shared.env")
|
||||
# Compare the entire configuration, including extra variables introduced by an unsafe copy.
|
||||
self.assertEqual(self.render(), baseline)
|
||||
|
||||
def test_consolidated_settings_reach_consumers_and_respect_root_precedence(self):
|
||||
api_services = ("api", "api_websocket")
|
||||
worker_services = (
|
||||
"worker",
|
||||
"worker_knowledge_fs_upgrade",
|
||||
"knowledge_fs_document_worker",
|
||||
"knowledge_fs_source_worker",
|
||||
"knowledge_fs_research_worker",
|
||||
"knowledge_fs_maintenance_worker",
|
||||
"knowledge_fs_dispatch_worker",
|
||||
)
|
||||
vector_clients = (*api_services, "worker", "worker_knowledge_fs_upgrade", "worker_beat")
|
||||
cases = [
|
||||
(
|
||||
"core-services/shared.defaults",
|
||||
(*api_services, *worker_services, "worker_beat"),
|
||||
{
|
||||
"CODE_MAX_STRING_LENGTH": ("500000", "600000"),
|
||||
"ENABLE_OTEL": ("true", "false"),
|
||||
"OTLP_BASE_ENDPOINT": ("http://collector:4318", "http://root-collector:4318"),
|
||||
"CELERY_BROKER_VISIBILITY_TIMEOUT": ("10800", "14400"),
|
||||
"OPS_TRACE_QUEUE": ("custom_traces", "root_traces"),
|
||||
"KNOWLEDGE_FS_BACKGROUND_POLL_INTERVAL_SECONDS": ("7", "9"),
|
||||
"AGENT_BACKEND_HOME_SNAPSHOT_TIMEOUT_SECONDS": ("60", "90"),
|
||||
"UNSTRUCTURED_API_URL": ("http://parser:8000", "http://root-parser:8000"),
|
||||
"S3_ENDPOINT": ("https://storage.example.test", "https://root-storage.example.test"),
|
||||
"TENCENT_COS_SECRET_KEY": ("app-storage-key", "root-storage-key"),
|
||||
},
|
||||
),
|
||||
(
|
||||
"core-services/api.defaults",
|
||||
api_services,
|
||||
{"GUNICORN_KEEP_ALIVE": ("20", "30"), "RESPECT_XFORWARD_HEADERS_ENABLED": ("false", "true")},
|
||||
),
|
||||
(
|
||||
"core-services/worker.defaults",
|
||||
worker_services,
|
||||
{"CELERY_AUTO_SCALE": ("true", "false"), "CELERY_MIN_WORKERS": ("2", "3")},
|
||||
),
|
||||
("vectorstores/weaviate.defaults", vector_clients, {"WEAVIATE_TOKENIZATION": ("field", "word")}),
|
||||
("vectorstores/qdrant.defaults", vector_clients, {"QDRANT_CLIENT_TIMEOUT": ("42", "60")}),
|
||||
(
|
||||
"vectorstores/oceanbase.defaults",
|
||||
vector_clients,
|
||||
{"OCEANBASE_VECTOR_HOST": ("custom-oceanbase", "root-oceanbase")},
|
||||
),
|
||||
("vectorstores/pgvector.defaults", vector_clients, {"PGVECTOR_MIN_CONNECTION": ("2", "3")}),
|
||||
("vectorstores/milvus.env.example", vector_clients, {"MILVUS_DATABASE": ("custom_dify", "root_dify")}),
|
||||
]
|
||||
root = self.project / ".env"
|
||||
initial_root = root.read_text()
|
||||
for template, consumers, values in cases:
|
||||
source = f"envs/{template}"
|
||||
target = source.removesuffix(".env.example").removesuffix(".defaults") + ".env"
|
||||
custom = {key: pair[0] for key, pair in values.items()}
|
||||
root_values = {key: pair[1] for key, pair in values.items()}
|
||||
with self.subTest(template=template):
|
||||
try:
|
||||
# Each stage changes one file; no other service override is present.
|
||||
self.override_root(custom)
|
||||
services = self.render()
|
||||
for name in consumers:
|
||||
for key, value in custom.items():
|
||||
self.assertEqual(services[name]["environment"][key], value, f"root only: {name}.{key}")
|
||||
root.write_text(initial_root)
|
||||
|
||||
self.copy_template(source, target, custom)
|
||||
services = self.render()
|
||||
for name in consumers:
|
||||
for key, value in custom.items():
|
||||
self.assertEqual(services[name]["environment"][key], value, f"service only: {name}.{key}")
|
||||
|
||||
self.override_root(root_values)
|
||||
services = self.render()
|
||||
for name in consumers:
|
||||
for key, value in root_values.items():
|
||||
self.assertEqual(
|
||||
services[name]["environment"][key], value, f"root precedence: {name}.{key}"
|
||||
)
|
||||
finally:
|
||||
(self.project / target).unlink(missing_ok=True)
|
||||
root.write_text(initial_root)
|
||||
|
||||
def test_existing_shared_overrides_and_empty_value_cleanup(self):
|
||||
values = {
|
||||
"API_WEBSOCKET_WORKER_AMOUNT": "3",
|
||||
"CELERY_MAX_WORKERS": "5",
|
||||
"QDRANT_URL": "http://existing-qdrant:6333",
|
||||
"PGVECTOR_HOST": "existing-pgvector",
|
||||
"MILVUS_DATABASE": "existing_dify",
|
||||
"CELERY_WORKER_AMOUNT": "",
|
||||
"SERVER_WORKER_CLASS": "",
|
||||
"GUNICORN_TIMEOUT": "",
|
||||
}
|
||||
override = self.project / "envs/core-services/shared.env"
|
||||
override.write_text("\n".join(f"{key}={value}" for key, value in values.items()) + "\n")
|
||||
services = self.render()
|
||||
for name in ("api", "api_websocket", "worker", "worker_knowledge_fs_upgrade", "worker_beat"):
|
||||
for key, value in values.items():
|
||||
self.assertEqual(services[name]["environment"][key], value, f"existing override: {name}.{key}")
|
||||
|
||||
# Cleaning accidental blanks in the existing file restores Docker defaults without replacing it.
|
||||
override.write_text("\n".join(f"{key}={value}" for key, value in values.items() if value) + "\n")
|
||||
services = self.render()
|
||||
self.assertEqual(services["worker"]["environment"]["CELERY_WORKER_AMOUNT"], "4")
|
||||
self.assertEqual(services["api"]["environment"]["SERVER_WORKER_CLASS"], "gevent")
|
||||
self.assertEqual(services["api"]["environment"]["GUNICORN_TIMEOUT"], "360")
|
||||
self.assertEqual(services["api_websocket"]["environment"]["API_WEBSOCKET_WORKER_AMOUNT"], "3")
|
||||
self.assertEqual(services["worker"]["environment"]["QDRANT_URL"], values["QDRANT_URL"])
|
||||
|
||||
def test_service_overrides_and_root_precedence(self):
|
||||
cases = [
|
||||
(
|
||||
"infrastructure/nginx",
|
||||
"nginx",
|
||||
"NGINX_CLIENT_MAX_BODY_SIZE",
|
||||
"NGINX_CLIENT_MAX_BODY_SIZE",
|
||||
"200M",
|
||||
"300M",
|
||||
),
|
||||
(
|
||||
"core-services/web",
|
||||
"web",
|
||||
"TOP_K_MAX_VALUE",
|
||||
"TOP_K_MAX_VALUE",
|
||||
"23",
|
||||
"24",
|
||||
),
|
||||
(
|
||||
"core-services/sandbox",
|
||||
"sandbox",
|
||||
"SANDBOX_WORKER_TIMEOUT",
|
||||
"WORKER_TIMEOUT",
|
||||
"120",
|
||||
"121",
|
||||
),
|
||||
(
|
||||
"core-services/plugin-daemon",
|
||||
"plugin_daemon",
|
||||
"PLUGIN_DAEMON_PORT",
|
||||
"SERVER_PORT",
|
||||
"5998",
|
||||
"5999",
|
||||
),
|
||||
(
|
||||
"vectorstores/weaviate",
|
||||
"weaviate",
|
||||
"WEAVIATE_QUERY_DEFAULTS_LIMIT",
|
||||
"QUERY_DEFAULTS_LIMIT",
|
||||
"66",
|
||||
"67",
|
||||
),
|
||||
(
|
||||
"core-services/api",
|
||||
"api",
|
||||
"API_SENTRY_DSN",
|
||||
"SENTRY_DSN",
|
||||
"https://api.example.test/1",
|
||||
"https://api.example.test/2",
|
||||
),
|
||||
(
|
||||
"core-services/worker",
|
||||
"worker",
|
||||
"API_SENTRY_DSN",
|
||||
"SENTRY_DSN",
|
||||
"https://worker.example.test/1",
|
||||
"https://api.example.test/2",
|
||||
),
|
||||
(
|
||||
"infrastructure/certbot",
|
||||
"certbot",
|
||||
"CERTBOT_DOMAIN",
|
||||
"CERTBOT_DOMAIN",
|
||||
"one.example.test",
|
||||
"two.example.test",
|
||||
),
|
||||
(
|
||||
"vectorstores/opensearch",
|
||||
"opensearch",
|
||||
"OPENSEARCH_JAVA_OPTS_MIN",
|
||||
"OPENSEARCH_JAVA_OPTS",
|
||||
"768m",
|
||||
"896m",
|
||||
),
|
||||
]
|
||||
for path, _, key, _, local, _ in cases:
|
||||
self.copy_template(f"envs/{path}.defaults", f"envs/{path}.env", {key: local})
|
||||
services = self.render()
|
||||
for _, service, _, native, local, _ in cases:
|
||||
expected = f"-Xms{local} -Xmx1024m" if native == "OPENSEARCH_JAVA_OPTS" else local
|
||||
self.assertEqual(
|
||||
services[service]["environment"][native],
|
||||
expected,
|
||||
f"{service}.{native}",
|
||||
)
|
||||
self.override_root({key: value for _, _, key, _, _, value in cases})
|
||||
services = self.render()
|
||||
for _, service, _, native, _, value in cases:
|
||||
expected = f"-Xms{value} -Xmx1024m" if native == "OPENSEARCH_JAVA_OPTS" else value
|
||||
self.assertEqual(
|
||||
services[service]["environment"][native],
|
||||
expected,
|
||||
f"{service}.{native}",
|
||||
)
|
||||
|
||||
def test_database_redis_overrides_reach_clients_and_commands(self):
|
||||
for name in (
|
||||
"shared",
|
||||
"api",
|
||||
"worker",
|
||||
"worker-beat",
|
||||
"plugin-daemon",
|
||||
"dify-agent",
|
||||
):
|
||||
self.copy_template(f"envs/core-services/{name}.defaults", f"envs/core-services/{name}.env")
|
||||
self.copy_template(
|
||||
"envs/databases/db-postgres.defaults",
|
||||
"envs/databases/db-postgres.env",
|
||||
{
|
||||
"DB_USERNAME": "custom_user",
|
||||
"DB_PASSWORD": "test-db-password",
|
||||
"DB_DATABASE": "custom_dify",
|
||||
"POSTGRES_MAX_CONNECTIONS": "321",
|
||||
},
|
||||
)
|
||||
self.copy_template(
|
||||
"envs/databases/redis.defaults",
|
||||
"envs/databases/redis.env",
|
||||
{"REDIS_PASSWORD": "test-redis-password"},
|
||||
)
|
||||
services = self.render()
|
||||
for name in ("api", "worker", "worker_beat", "plugin_daemon"):
|
||||
values = services[name]["environment"]
|
||||
self.assertEqual(values["DB_USERNAME"], "custom_user", name)
|
||||
self.assertEqual(values["DB_PASSWORD"], "test-db-password", name)
|
||||
self.assertEqual(values["REDIS_PASSWORD"], "test-redis-password", name)
|
||||
for name in ("api", "worker", "worker_beat"):
|
||||
self.assertEqual(
|
||||
services[name]["environment"]["CELERY_BROKER_URL"],
|
||||
"redis://:test-redis-password@redis:6379/1",
|
||||
name,
|
||||
)
|
||||
self.assertEqual(
|
||||
services["db_postgres"]["environment"]["POSTGRES_PASSWORD"],
|
||||
"test-db-password",
|
||||
)
|
||||
self.assertEqual(services["plugin_daemon"]["environment"]["DB_DATABASE"], "dify_plugin")
|
||||
self.assertEqual(services["redis"]["environment"]["REDISCLI_AUTH"], "test-redis-password")
|
||||
self.assertEqual(
|
||||
services["agent_backend"]["environment"]["DIFY_AGENT_REDIS_URL"],
|
||||
"redis://:test-redis-password@redis:6379/2",
|
||||
)
|
||||
# Execute the command with a harmless stand-in for the image entrypoint.
|
||||
executable = self.project / "docker-entrypoint.sh"
|
||||
executable.write_text('#!/bin/sh\nprintf "%s\\n" "$@"\n')
|
||||
executable.chmod(0o755)
|
||||
for service in ("db_postgres", "db_mysql", "redis"):
|
||||
config = services[service]
|
||||
command = [arg.replace("$$", "$") for arg in config["command"]]
|
||||
env = {
|
||||
**config["environment"],
|
||||
"PATH": f"{self.project}:{os.environ['PATH']}",
|
||||
}
|
||||
if service == "redis":
|
||||
env["REDIS_PASSWORD"] = "literal $(touch should-not-exist) ; password"
|
||||
result = subprocess.run(
|
||||
command,
|
||||
cwd=self.project,
|
||||
env=env,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
args = result.stdout.splitlines()
|
||||
self.assertEqual(
|
||||
args[0],
|
||||
{
|
||||
"db_postgres": "postgres",
|
||||
"db_mysql": "mysqld",
|
||||
"redis": "redis-server",
|
||||
}[service],
|
||||
)
|
||||
if service == "db_postgres":
|
||||
self.assertIn("max_connections=321", args)
|
||||
if service == "redis":
|
||||
self.assertEqual(args[-1], env["REDIS_PASSWORD"])
|
||||
self.assertFalse((self.project / "should-not-exist").exists())
|
||||
|
||||
def test_root_plugin_credentials_reach_every_consumer(self):
|
||||
for name in ("shared", "api", "worker", "worker-beat", "plugin-daemon", "dify-agent"):
|
||||
self.copy_template(f"envs/core-services/{name}.defaults", f"envs/core-services/{name}.env")
|
||||
api_services = (
|
||||
"api",
|
||||
"api_websocket",
|
||||
"worker",
|
||||
"worker_knowledge_fs_upgrade",
|
||||
"knowledge_fs_document_worker",
|
||||
"knowledge_fs_source_worker",
|
||||
"knowledge_fs_research_worker",
|
||||
"knowledge_fs_maintenance_worker",
|
||||
"knowledge_fs_dispatch_worker",
|
||||
)
|
||||
cases = {
|
||||
"PLUGIN_DAEMON_KEY": {
|
||||
**dict.fromkeys((*api_services, "worker_beat"), "PLUGIN_DAEMON_KEY"),
|
||||
"plugin_daemon": "SERVER_KEY",
|
||||
"agent_backend": "DIFY_AGENT_PLUGIN_DAEMON_API_KEY",
|
||||
},
|
||||
"PLUGIN_DIFY_INNER_API_KEY": {
|
||||
**dict.fromkeys(api_services, "INNER_API_KEY_FOR_PLUGIN"),
|
||||
"plugin_daemon": "DIFY_INNER_API_KEY",
|
||||
"agent_backend": "DIFY_AGENT_INNER_API_KEY",
|
||||
"knowledge_fs": "DIFY_INNER_API_KEY",
|
||||
},
|
||||
}
|
||||
for key, consumers in cases.items():
|
||||
value = f"custom-{key.lower()}"
|
||||
self.override_root({key: value})
|
||||
services = self.render()
|
||||
for name, native in consumers.items():
|
||||
self.assertEqual(services[name]["environment"][native], value, f"{name}.{native}")
|
||||
if key == "PLUGIN_DIFY_INNER_API_KEY":
|
||||
for name in api_services:
|
||||
if name.startswith("knowledge_fs_"):
|
||||
self.assertEqual(services[name]["environment"]["DIFY_INNER_API_KEY"], value, name)
|
||||
|
||||
def test_websocket_uses_copied_api_settings(self):
|
||||
self.copy_template(
|
||||
"envs/core-services/api.defaults",
|
||||
"envs/core-services/api.env",
|
||||
{"API_WEBSOCKET_WORKER_AMOUNT": "3"},
|
||||
)
|
||||
config = self.render()["api_websocket"]
|
||||
# Stand in for the image's entrypoint; exercise the actual shell expansion.
|
||||
command = [arg.replace("$$", "$") for arg in config["entrypoint"]]
|
||||
command[-1] = command[-1].replace("exec /bin/bash /entrypoint.sh", 'printf "%s" "$SERVER_WORKER_AMOUNT"')
|
||||
result = subprocess.run(
|
||||
command,
|
||||
env=config["environment"],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
self.assertEqual(result.stdout, "3")
|
||||
|
||||
def test_e2b_overlay_preserves_service_credentials(self):
|
||||
self.copy_template("docker-compose.e2b.yaml", "docker-compose.e2b.yaml")
|
||||
self.copy_template(
|
||||
"envs/core-services/dify-agent.defaults",
|
||||
"envs/core-services/dify-agent.env",
|
||||
{
|
||||
"DIFY_AGENT_E2B_API_KEY": "service-api-key",
|
||||
"DIFY_AGENT_E2B_TEMPLATE": "custom-template",
|
||||
},
|
||||
)
|
||||
values = self.render("-f", "docker-compose.yaml", "-f", "docker-compose.e2b.yaml")["agent_backend"][
|
||||
"environment"
|
||||
]
|
||||
self.assertEqual(values["DIFY_AGENT_RUNTIME_BACKEND"], "e2b")
|
||||
self.assertEqual(values["DIFY_AGENT_E2B_API_KEY"], "service-api-key")
|
||||
self.assertEqual(values["DIFY_AGENT_E2B_TEMPLATE"], "custom-template")
|
||||
|
||||
def test_generator_creates_only_root_env_and_preserves_edits(self):
|
||||
for source in (
|
||||
"generate_docker_compose",
|
||||
".env.example",
|
||||
"docker-compose-template.yaml",
|
||||
"envs/security.env.example",
|
||||
):
|
||||
self.copy_template(source, source)
|
||||
(self.project / ".env").unlink()
|
||||
command = [sys.executable, str(self.project / "generate_docker_compose")]
|
||||
subprocess.run(command, check=True, capture_output=True)
|
||||
self.assertEqual(
|
||||
(self.project / ".env").read_text(),
|
||||
(DOCKER_DIR / ".env.example").read_text(),
|
||||
)
|
||||
self.assertEqual(list((self.project / "envs").rglob("*.env")), [])
|
||||
(self.project / ".env").write_text("COMPOSE_PROFILES=custom\n")
|
||||
subprocess.run(command, check=True, capture_output=True)
|
||||
self.assertEqual((self.project / ".env").read_text(), "COMPOSE_PROFILES=custom\n")
|
||||
|
||||
def test_runtime_secrets_stay_in_their_service(self):
|
||||
self.copy_template(
|
||||
"envs/core-services/api.defaults",
|
||||
"envs/core-services/api.env",
|
||||
{"PASSWORD_PEPPER": "api-only-test-secret"},
|
||||
)
|
||||
self.copy_template(
|
||||
"envs/core-services/web.defaults",
|
||||
"envs/core-services/web.env",
|
||||
{"NEXT_PUBLIC_ENABLE_HITL_IM": "true"},
|
||||
)
|
||||
services = self.render()
|
||||
self.assertEqual(services["web"]["environment"]["NEXT_PUBLIC_ENABLE_HITL_IM"], "true")
|
||||
self.assertEqual(services["api"]["environment"]["PASSWORD_PEPPER"], "api-only-test-secret")
|
||||
for name in ("web", "plugin_daemon", "nginx", "db_postgres", "agent_backend"):
|
||||
self.assertNotIn("PASSWORD_PEPPER", services[name]["environment"], name)
|
||||
|
||||
def test_generated_compose_matches_template(self):
|
||||
self.assertTrue(
|
||||
(DOCKER_DIR / "docker-compose.yaml")
|
||||
.read_text()
|
||||
.endswith((DOCKER_DIR / "docker-compose-template.yaml").read_text())
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user