| name | dify-docs-env-vars |
| description | Use when writing, rewriting, or auditing environment variable documentation for Dify self-hosted deployment. Applies to en/self-host/configuration/environments.mdx. Covers the full process from codebase tracing to user-facing descriptions.
|
Dify Environment Variable Documentation
Before Starting
Read these shared guides:
writing-guides/style-guide.md
writing-guides/formatting-guide.md
writing-guides/glossary.md
Source of Truth: docker/.env.example + docker/envs/**/*.env.example
After Dify PR #31586, the supported self-host knob surface is split across:
docker/.env.example — essential startup values
docker/envs/**/*.env.example — categorized optional vars (core-services, databases, infrastructure, security, vectorstores, middleware)
The verifier reads both. Pass --env-example docker/.env.example --env-example docker/envs (the second arg is a directory; the verifier globs **/*.env.example recursively).
| Var location | Action |
|---|
In any .env.example file, uncommented | Document. |
In any .env.example file, commented (#FOO=bar) | Document; add to Verifier false positives in ignored-vars.md (the verifier can't parse defaults from comments). |
Only in api/configs/ Pydantic, not in any .env.example | Don't document. Upstream-deferred; file a PR adding it to the appropriate .env.example file first. |
Removed from .env.example because the code no longer reads it | Remove from docs. Documenting unreferenced vars implies they still take effect. Discoverability for upgraders belongs in upstream Dify release notes, not this docs site. |
The verifier's "extra in docs" signal is not an escape hatch. Never suppress it for Pydantic-only vars via ignored-vars.md.
Four-Step Process
Pull the latest Dify code before tracing. In the Dify codebase directory:
git fetch origin && git checkout main && git pull origin main
This process applies to every variable without exception. Do not skip variables because they seem "obvious" — every variable must be traced, explained, and described.
Step 1: Trace the Variable in the Codebase
Agent granularity: When using subagents for tracing, assign 3–5 related variables per agent.
Tracing depth depends on variable type:
- Python config variables (defined in
api/configs/): Full tracing — find definition, all usage locations, and behavior when empty vs set.
- Frontend variables (mapped in
web/docker/entrypoint.sh): Trace from entrypoint.sh to find the Docker-to-NEXT_PUBLIC_* mapping, verify the default in both docker/.env.example and web/.env.example, and check whether the variable is also used in Python code (dual-purpose). For Next.js-only variables (UI knobs like MAX_TOOLS_NUM), light verification is sufficient.
- Docker/container service variables (only in
docker-compose.yaml): Light verification — grep to confirm the variable is not used in Python code, then document from .env.example comments.
- Plugin daemon variables (
PLUGIN_* not in api/configs/): Document from .env.example comments.
For full tracing, search the Dify codebase:
- Find the definition in
api/configs/ — note the Pydantic field type, default, description, and any validation_alias (fallback) settings.
- Find every usage — grep for both the env var name and the Python attribute (e.g.,
dify_config.VARIABLE_NAME). Read surrounding code to understand what each usage does.
- Determine behavior when empty vs set — trace fallback chains and identify what features break.
Step 2: Write a Plain-Language Explanation
Write an explanation covering:
- What the variable actually does (in practical terms, not code terms)
- Specific features that depend on it (name them)
- What happens if left empty (what breaks, what falls back)
- What happens if set (what works)
- Key code locations (file paths, no line numbers — they shift)
Save to deep-dive.md (in this skill directory) under the appropriate section heading.
Step 3: Write the User-Facing Description
Transform the explanation into a concise documentation description. The description must:
- Lead with the practical impact, not the technical mechanism
- Name the features that require this variable (e.g., "Required for the Human Input node" not "used for frontend references")
- Explain what breaks if misconfigured (e.g., "If empty, email links will be broken")
- Mention fallback behavior if the variable has one (e.g., "falls back to
CONSOLE_API_URL")
- Include relationships with other variables when relevant
- End with an example value for non-obvious variables
Step 4: Confirm with Reviewer
Present the proposed description to the user for review before editing the documentation file.
Document Structure
The env var doc is organized into three sections following docker/.env.example section order:
- Backend (API + Worker) — Python API server and Celery worker variables.
- Frontend (Web) — Next.js frontend variables. Uses
<Tabs> to show Docker and source code variable names.
- Infrastructure (Docker Compose / AWS AMI Only) — database, Redis, Nginx, and other container variables. Not applicable to source code deployments.
When to use tables: Groups of related, straightforward variables (connection settings, credentials, tuning knobs).
When to use individual headings: Important variables needing explanation — typically enum-type selectors (STORAGE_TYPE, VECTOR_STORE) or variables where the "why" matters (SECRET_KEY, FILES_URL).
When to use tabs: Frontend section variables where Docker and source code deployments use different variable names. Tabs cannot be placed inside table cells, so all tabbed variables require individual headings.
When to use accordions: Provider-specific configuration (storage backends, vector databases, mail providers) — users only need one provider.
Reader Persona
Same audience as en/self-host/ documentation (see dify-docs-guides skill): DevOps engineers and system administrators deploying Dify. Assume strong infrastructure knowledge.
Additional context for env var docs: Readers are actively configuring a deployment. They need to know what each variable does, when to change it, and what breaks if they get it wrong. They are not reading linearly—they are scanning for a specific variable.
Style Overrides
Rules specific to env var docs (override or extend the shared style guide):
- Use
(empty) for empty-string defaults, not "" or blank
- For empty defaults with a fallback:
(empty; falls back to X) or (empty; defaults to X)
- Never include real or example secret keys — GitHub push protection blocks
sk-* patterns. Use descriptions like (pre-filled in .env.example; must be replaced for production)
Consistency over variety in reference tables. The general style guide says to vary sentence patterns. In reference tables, consistency aids scanning. Use predictable patterns for connection credentials (hostname, port, username, password) across providers. Vary descriptions only when variables genuinely differ in behavior or purpose.
Variable descriptions should be self-contained. The general style guide says not to restate the heading. Variable descriptions must state what the variable does—even if the name partially implies it. Not all variable names are self-explanatory, and users may arrive at a description via search without seeing the surrounding section context.
Include actionable technical mechanisms. The general style guide favors user outcomes over technical mechanisms. For env var docs, include technical mechanisms that help users configure, troubleshoot, or understand trade-offs—algorithm names, encoding behavior, fallback chains, version requirements. Exclude mechanisms that only describe code architecture—factory patterns, lazy imports, class names—unless understanding them is necessary for configuration.
- Keep: "URL-encoded in the connection string, so
@, :, % are safe to use", "HMAC-SHA256", "Requires Milvus >= 2.5.0", "Falls back to CONSOLE_API_URL"
- Remove: "Dify's storage dispatcher lazily imports the selected backend", "Sends POST to /v1/sandbox/run with X-Api-Key header"
No specific recommended values for tuning parameters. For numeric tuning parameters without clear boundaries (connection pool sizes, worker counts, timeouts, buffer sizes), do not prescribe values. Describe the symptom that indicates the value needs changing: "If you experience connection rejections under load, try increasing this value." Exception: when a value has a well-established recommendation (e.g., PostgreSQL shared_buffers = 25% of RAM), include it with a reference link.
Description Anti-Patterns
| Anti-Pattern | Better |
|---|
| "Used for frontend references" | "Required for the Human Input node — form links in email notifications are built from this URL" |
| "The backend URL of the console API" | "Set this if you use OAuth login (GitHub, Google) or Notion integration — these features need an absolute callback URL" |
| "Upload file size limit, default 15" | "Maximum file size in MB for uploads" |
| Restating the code comment verbatim | Explaining when you'd change it and what happens if you don't |
Verification
Run after completing any documentation change:
python3 .claude/skills/dify-docs-env-vars/verify-env-docs.py \
--env-example <path-to-docker/.env.example> \
--docs <path-to-environments.mdx>
The script reports:
- Missing from docs: Variables in
.env.example not yet documented (address over time)
- Extra in docs: Variables documented but not in
.env.example (verify manually)
- Default mismatches: Documented defaults that don't match
.env.example — must be zero before work is complete
Use .env.example defaults (what Docker Compose users actually get), not Pydantic code defaults.
Intentionally ignored variables
Some variables in .env.example are deliberately not documented (Cloud-only, experimental, or verifier false positives). The verifier reads these from ignored-vars.md (same directory) and filters them out. When you:
- Remove a variable from the docs as Cloud-only → add it under Cloud-only (SaaS) in
ignored-vars.md.
- Skip documenting an experimental or internal flag → add it under Experimental / internal.
- Document a supported variable whose
.env.example entry is commented out (e.g., #FOO=bar) → add it under Verifier false positives. This bucket is only for vars that exist in .env.example in commented form. Do not use it to suppress verifier signal for vars that are absent from .env.example entirely — those are upstream-deferred (see Source of Truth) and must not be documented.
Every entry must include a source reference (PR, commit, or audit date).
Translation
The automated translation pipeline does not cover en/self-host/configuration/environments.mdx. After editing that English file, manually update zh/self-host/configuration/environments.mdx and ja/self-host/configuration/environments.mdx to match.
Post-Writing Verification
After completing the document, run the post-writing checks listed in writing-guides/index.md#post-writing-verification.