Dify Docker Compose 部署实战指南:三层 .env 配置体系、中间件开发环境与变量同步工具
本篇指南基于 Dify 仓库 docker/ 目录的官方部署文档,系统讲解如何用 Docker Compose 完成 Dify 的自托管部署:从 .env 三层配置体系的设计原理,到向量库切换、SSL 证书签发、OpenTelemetry 接入的完整命令流程,再到开发中间件环境与 dify-env-sync 变量同步工具的使用。读完本文,你可以独立完成一次可复制的 Dify 容器化部署,并理解每个配置项背后的 Compose 编排机制。
一、docker 目录的定位与核心更新
Dify 当前版本将自托管部署统一收敛到 docker/ 目录,围绕 docker-compose.yaml 单一编排文件提供生产部署能力。官方 README(docker/README.md)声明了三个关键设计决策:
- Certbot 容器集成:
docker-compose.yaml内置certbot服务,负责签发与自动续期 SSL 证书,保障 HTTPS 安全连接。 - 持久化环境变量:启动默认值由 .env.example 提供,本地实际值存放于
.env,配置在多次部署间保持持久。.env即本地启动文件——默认部署只需从.env.example复制一份;进阶可选项则拆分在envs/*.env.example中。 - 向量库统一编排:所有向量数据库服务都由同一个
docker-compose.yaml管理,只需在.env中修改VECTOR_STORE变量即可在milvus、weaviate、opensearch等后端之间切换。
从源码结构看,docker/ 目录的组织方式直接体现了这一设计:
- 编排文件:docker-compose.yaml(主部署)、docker-compose.middleware.yaml(开发中间件);
- 配置模板:根级 .env.example 与 envs/ 下按主题分组的
*.env.example; - 配套脚本:dify-env-sync.sh / dify-env-sync.py(变量同步)、generate_docker_compose(编排文件生成器);
- 服务定制:nginx/、certbot/、ssrf_proxy/、pgvector/、tidb/ 等目录存放各服务的入口脚本与配置模板。
二、Docker Compose 完整部署流程
2.1 前置条件
- 系统已安装 Docker 与 Docker Compose v2.24.0 及以上版本(
env_file的required: false可选文件语法依赖较新的 Compose 版本)。
2.2 环境准备
进入 docker 目录后,按官方文档步骤操作:
cd docker
cp .env.example .env
# 按需修改 .env 中的关键启动值
# 如需进阶配置,将 envs/ 下对应的 *.env.example 复制为去掉 .example 后缀的文件
根级 .env 只需承载启动必需的默认值;若你需要维护一份完整的自定义 .env,官方建议使用环境同步工具(见第六节)在升级时保持与最新 .env.example 对齐。
2.3 启动服务并选择向量库
docker compose up -d
切换向量库只需修改 .env 中的 VECTOR_STORE 变量。当前 docker/envs/vectorstores/ 目录共提供 17 个后端的配置模板:weaviate、milvus、qdrant、opensearch、elasticsearch、pgvector、pgvecto-rs、chroma、oceanbase、couchbase、seekdb、iris、oracle、opengauss、myscale、matrixone、vastbase。每个模板对应一个 docker/envs/vectorstores/ 下的 *.env.example 文件,按需复制为 *.env 后再启动即可。
2.4 编排文件的生成机制
值得注意的是,docker-compose.yaml 文件头部明确标注:
# WARNING: This file is auto-generated by generate_docker_compose
# Do not modify this file directly. Instead, update the .env.example
# or docker-compose-template.yaml and regenerate this file.
即它由 generate_docker_compose 脚本基于 docker-compose-template.yaml 生成,并会自动把 envs/ 下所有 *.env.example 复制为同名 .env 文件(用于 CI/CD 环境保证 env_file 引用存在)。这意味着手工修改 docker-compose.yaml 会在重新生成时丢失,定制行为应落在 .env / envs/*.env 文件中——这也是官方把“自定义配置迁入 .env”作为升级迁移要求的原因。
三、三层配置文件体系:.env、.env.example 与 envs/
官方文档对配置文件的职责划分非常明确:
| 文件 | 职责 |
|---|---|
| .env.example | Docker Compose 部署的必需启动默认值,应只保留启动所必需变量,不放可选、进阶或供应商特定变量 |
.env |
由 .env.example 复制而来的本地启动值,包含你的本地修改 |
| envs/*.env.example | 按主题分组的可选进阶配置(数据库、向量库、基础设施、核心服务) |
变量加载优先级:Docker Compose 先读取 envs/*.env 文件,最后读取根级 .env,因此 .env 中的值优先。这一点可以从 docker-compose.yaml 中共享配置锚点 x-shared-api-worker-config 的 env_file 列表得到印证——它按顺序引用 envs/core-services/shared.env、各向量库与数据库的 envs/*.env、以及位于列表末尾的 ./.env,且每一项都标记 required: false,表示对应文件不存在时跳过(默认部署只依赖根 .env)。
envs/ 目录的实际分组结构(以仓库现状为准):
envs/core-services/:shared.env.example(API/Worker 共享配置,变量最多)、api.env.example、web.env.example、worker.env.example、worker-beat.env.example、sandbox.env.example、plugin-daemon.env.example等;envs/databases/:db-postgres.env.example、db-mysql.env.example、redis.env.example;envs/vectorstores/:17 个向量库配置模板;envs/infrastructure/:nginx、certbot、ssrf-proxy、minio、etcd、milvus-standalone;- 根级:
security.env.example(密钥与 TLS 相关)、middleware.env.example(开发中间件)。
关键环境变量速查
根级 .env.example 提供核心启动配置,进阶配置在 envs/*.env.example。官方文档列出的关键分组如下:
1. 通用 URL 变量
CONSOLE_API_URL、CONSOLE_WEB_URL、SERVICE_API_URL、APP_API_URL、APP_WEB_URL:API 与前端服务的公网地址;SERVER_CONSOLE_API_URL:Web 服务端请求使用的内部 API 地址,当INTERNAL_FILES_URL未设置时也是 API 侧内部文件 URL 生成的默认回退值。标准 Compose 部署保持默认http://api:5001,仅在服务需要通过其他内部地址访问 API 时才修改;FILES_URL、INTERNAL_FILES_URL:文件下载与预览的公网/内部基础 URL;ENDPOINT_URL_TEMPLATE、NEXT_PUBLIC_SOCKET_URL、TRIGGER_URL:其他服务地址。
2. 服务运行配置
LOG_LEVEL、DEBUG、FLASK_DEBUG:日志与调试开关;SECRET_KEY:用于签发 Session、JWT 与文件 URL。留空时 Dify 会在存储目录自动生成一个持久化密钥,也可以自行指定一个唯一值(.env.example 中有明确注释);MIGRATION_ENABLED:是否执行数据库迁移,默认true。
3. 数据库配置:DB_USERNAME、DB_PASSWORD、DB_HOST、DB_PORT、DB_DATABASE(PostgreSQL 默认值见 .env.example:postgres / difyai123456 / db_postgres / 5432 / dify);DB_TYPE 用于在 postgresql 与 mysql 间切换。
4. Redis 配置:REDIS_HOST、REDIS_PORT、REDIS_PASSWORD;REDIS_KEY_PREFIX 为可选的全局命名空间前缀,作用于 Redis 键、topic、stream 及 Celery Redis transport 相关产物。
5. Celery 配置:CELERY_BROKER_URL(消息代理地址,默认指向内部 Redis 的 1 号库)。
6. 存储配置:STORAGE_TYPE、OPENDAL_SCHEME、OPENDAL_FS_ROOT 为默认本地文件存储设置;S3、Azure Blob、Google Storage 等可选后端从 envs/ 下对应文件配置。
7. 向量数据库配置:VECTOR_STORE 指定类型(如 weaviate、milvus),各后端具体参数如 WEAVIATE_ENDPOINT、MILVUS_URI 分别位于 docker/envs/vectorstores/ 中对应模板。
8. CORS 配置:WEB_API_CORS_ALLOW_ORIGINS、CONSOLE_CORS_ALLOW_ORIGINS。
9. OpenTelemetry 配置:ENABLE_OTEL 启用 API 侧的 OTel Collector;OTLP_BASE_ENDPOINT 指定 OTLP 导出端点(详见第五节)。
10. 其他服务专属变量:nginx、redis、db、各向量库等服务的专属变量直接在 Compose 文件中引用,按需在各服务对应的 envs/*.env.example 中定制。
四、SSL 证书部署(Certbot)
SSL 能力由 certbot/ 子目录提供,包含 README、容器入口脚本 docker-entrypoint.sh 与证书更新模板 update-cert.template.txt。整个流程通过 --profile certbot 激活,不启用该 profile 的旧服务器仍可继续使用 nginx/ssl 证书目录(向后兼容)。
第一步:获取 Let's Encrypt 证书。在 .env 中设置:
NGINX_SSL_CERT_FILENAME=fullchain.pem
NGINX_SSL_CERT_KEY_FILENAME=privkey.pem
NGINX_ENABLE_CERTBOT_CHALLENGE=true
CERTBOT_DOMAIN=your_domain.com
CERTBOT_EMAIL=example@your_domain.com
然后执行:
docker network prune
docker compose --profile certbot up --force-recreate -d
容器启动后,进入 certbot 容器签发证书:
docker compose exec -it certbot /bin/sh /update-cert.sh
第二步:启用 HTTPS。在 .env 中追加 NGINX_HTTPS_ENABLED=true,再执行:
docker compose --profile certbot up -d --no-deps --force-recreate nginx
证书续期(日常运维命令):
docker compose exec -it certbot /bin/sh /update-cert.sh
docker compose exec nginx nginx -s reload
测试选项:CERTBOT_OPTIONS=--dry-run 可用于模拟签发;修改该选项后需先重建 certbot 容器再执行更新脚本:
docker compose --profile certbot up -d --no-deps --force-recreate certbot
docker compose exec -it certbot /bin/sh /update-cert.sh
docker compose exec nginx nginx -s reload
五、OpenTelemetry Collector 接入
官方文档给出的启用路径是:
- 将 docker/envs/core-services/shared.env.example 复制为同目录下的
shared.env; - 设置
ENABLE_OTEL=true并配置OTLP_BASE_ENDPOINT; - 按需微调同一文件中的其他
OTEL_*旋钮。
从 shared.env.example 源码可以看到完整的可调参数集:默认 ENABLE_OTEL=false、OTLP_BASE_ENDPOINT=http://localhost:4318(OTLP HTTP 默认端口),并暴露了采样与导出批处理参数 OTEL_EXPORTER_TYPE、OTEL_SAMPLING_RATE(默认 0.1)、OTEL_BATCH_EXPORT_SCHEDULE_DELAY、OTEL_MAX_QUEUE_SIZE、OTEL_MAX_EXPORT_BATCH_SIZE、OTEL_METRIC_EXPORT_INTERVAL、OTEL_BATCH_EXPORT_TIMEOUT、OTEL_METRIC_EXPORT_TIMEOUT,以及 OTLP_TRACE_ENDPOINT / OTLP_METRIC_ENDPOINT 的端点级覆盖,适合按生产环境吞吐特征调优。
六、开发中间件环境(docker-compose.middleware.yaml)
如果你要基于源码开发 Dify,官方提供了独立的中台编排文件 docker-compose.middleware.yaml,用于启动数据库、缓存等必需中间件,避免完整拉取生产栈。
步骤:
cd docker
# 1. 创建 middleware.env
cp envs/middleware.env.example middleware.env
# 2. 启动中间件服务
docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d
该命令会按 middleware.env 中的 DB_TYPE 启动 PostgreSQL 或 MySQL,外加内置的 Weaviate 实例。关键机制是:Compose 会自动从 middleware.env 加载 COMPOSE_PROFILES=${DB_TYPE:-postgresql},weaviate,因此无需额外 --profile 参数;想要不同的服务组合,直接改 middleware.env 即可。仓库中 dev/start-docker-compose 脚本执行的就是同一条命令,说明该流程也是官方本地开发工作流的一部分。
从 middleware.env.example 与编排文件源码看,这个开发栈包含:
- PostgreSQL 15 / MySQL 8.0:
db_postgres服务以postgresqlprofile 启动,max_connections、shared_buffers、work_mem等参数全部通过POSTGRES_*变量注入postgres命令行;db_mysql则以mysqlprofile 启动,用innodb_buffer_pool_size等MYSQL_*变量调优,健康检查特意改用真实SELECT 1而非mysqladmin ping(注释说明了原因:mysql 8.0 在 TCP 监听阶段 ping 已可通过但初始化未完成,会导致首个真实查询报 "Lost connection"); - Redis 6:
redis:6-alpine,通过REDIS_PASSWORD设密码,数据落盘到./volumes/redis/data; - DifySandbox(
langgenius/dify-sandbox:0.2.15):代码执行沙箱,API_KEY、WORKER_TIMEOUT、网络代理均走SANDBOX_*变量,且默认通过ssrf_proxy(Squid 代理,端口 3128)限制出站网络; - SSRF 代理:
SSRF_HTTP_PORT=3128、SSRF_PROXY_ALLOW_PRIVATE_IPS等变量控制私网访问白名单; - Plugin Daemon 相关变量:
PLUGIN_DAEMON_URL、PLUGIN_DIFY_INNER_API_URL默认指向host.docker.internal,表明该栈设计为“中间件跑在容器、Dify 主服务跑在宿主机”的开发拓扑。
各服务宿主机端口暴露由 EXPOSE_* 系列变量统一控制(如 EXPOSE_POSTGRES_PORT=5432、EXPOSE_REDIS_PORT=6379),不需要的服务可在 middleware.env 中调整。
七、从 docker-legacy 迁移
对仍在使用旧版 docker-legacy 目录的用户,官方给出三步迁移路径:
- 熟悉变更:先理解新的
.env配置体系与 Docker Compose 结构; - 迁移自定义配置:如果你曾直接修改过
docker-compose.yaml、ssrf_proxy/squid.conf或nginx/conf.d/default.conf,需要把这些改动转写为.env中的等价变量(新架构下 Compose 文件是生成物,配置入口全部收敛到环境变量); - 数据迁移:确保数据库、缓存等服务的数据已备份,并按新目录结构(如
volumes/db、volumes/redis、volumes/weaviate)迁移到新卷布局。
八、环境变量同步工具 dify-env-sync.sh
升级 Dify 或拉取最新代码后,新的启动必需变量只会出现在 .env.example 中,而进阶/供应商特定变量则出现在 envs/ 下的对应文件里。如果你维护着一份从 .env.example 复制的完整 .env,仓库提供同步工具 dify-env-sync.sh(配套实现为 dify-env-sync.py):
该工具执行单向同步(
.env.example→.env),永远不会自动覆盖.env中已有的值。
它做的事情:
- 改动前自动备份当前
.env; - 从
.env.example同步新增的环境变量; - 完整保留
.env中所有自定义值; - 展示差异,并列出已从
.env.example中移除的变量供人工审查。
备份行为:同步前当前 .env 会保存到 env-backup/ 目录,使用带时间戳的文件名,例如 env-backup/.env.backup_20231218_143022。
适用场景:升级到含完整 .env 的新版本后;.env.example 新增变量后;维护大型或深度定制的 .env 文件时。
使用方式:
# 授予执行权限(首次)
chmod +x dify-env-sync.sh
# 执行同步
./dify-env-sync.sh
九、部署要点小结
- 配置入口唯一化:所有定制都应落到
.env与envs/*.env,docker-compose.yaml是generate_docker_compose的生成产物,直接修改会被覆盖; - 优先级规则:
envs/*.env先加载、根.env后加载且优先,覆盖关系清晰可控; - 向量库即插即用:改一个
VECTOR_STORE变量 + 复制对应envs/vectorstores/*.env即可切换 17 种后端之一; - 生产与开发分离:
docker-compose.yaml面向生产全栈(含 certbot、nginx、ssrf_proxy),docker-compose.middleware.yaml面向源码开发,两者共享同一套envs/模板体系; - 升级安全网:
dify-env-sync.sh的单向同步 + 时间戳备份机制,让版本间的环境变量演进可追溯、可回滚。
以上所有文件与命令均以当前仓库实际内容为准;若你在升级过程中遇到变量缺失,优先核对 .env.example 与对应 envs/*.env.example 的注释说明,再结合 docker compose config 检查最终解析结果。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
