Docker 构建流程与多阶段镜像(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/langgenius/dify/3.1-docker-build-process-and-multi-stage-images
翻译时间:2026-05-27T08:44:22.889Z
翻译模型:deepseek-chat
原文字符数:10128
项目:Dify (dify)
---
Docker 构建过程与多阶段镜像
相关源文件
以下文件被用作生成此 Wiki 页面的上下文:
.github/labeler.yml.github/workflows/api-tests.yml.github/workflows/autofix.yml.github/workflows/build-push.yml.github/workflows/db-migration-test.yml.github/workflows/docker-build.yml.github/workflows/main-ci.yml.github/workflows/pyrefly-diff-comment.yml.github/workflows/pyrefly-diff.yml.github/workflows/style.yml.github/workflows/tool-test-sdks.yaml.github/workflows/translate-i18n-claude.yml.github/workflows/trigger-i18n-sync.yml.github/workflows/vdb-tests-full.yml.github/workflows/vdb-tests.yml.github/workflows/web-tests.ymlapi/Dockerfiledepot.jsonweb/.env.exampleweb/Dockerfileweb/app/layout.tsxweb/config/index.tsweb/docker/entrypoint.shweb/types/feature.ts
目的与范围
本文档描述了 Dify 平台中 API 和 Web 服务的 Docker 镜像构建过程。内容涵盖多阶段 Dockerfile 架构、构建优化策略、依赖安装以及镜像创建流程。有关运行时容器配置和 MODE 环境变量的信息,请参见环境配置与运行时模式。有关部署编排的详细信息,请参见服务拓扑与 Docker Compose 堆栈。
---
多阶段构建架构
API 和 Web 服务均采用多阶段 Docker 构建,以在保持构建时依赖与运行时依赖清晰分离的同时,最小化最终镜像体积。
API 多阶段构建流程
API 镜像构建遵循 api/Dockerfile 中定义的三个不同阶段。
graph TB
subgraph "阶段 1:基础镜像 [api/Dockerfile:2-10]"
Base["python:3.12-slim-bookworm<br/>UV_VERSION=0.8.9<br/>WORKDIR=/app/api"]
end
subgraph "阶段 2:依赖包 [api/Dockerfile:12-29]"
Packages["安装系统依赖<br/>g++, libmpfr-dev, libmpc-dev"]
PythonDeps["uv sync --frozen --no-dev<br/>复制:pyproject.toml, uv.lock<br/>复制:providers/"]
end
subgraph "阶段 3:生产环境 [api/Dockerfile:31-123]"
ProdRuntime["系统运行时依赖<br/>Node.js 22, fonts-noto-cjk,<br/>libmagic1, media-types"]
CopyVenv["COPY --from=packages<br/>.venv 目录"]
NLTKDownload["下载 NLTK 数据<br/>punkt, stopwords"]
TiktokenCache["预热 tiktoken 缓存<br/>gpt2 编码"]
AppCode["复制应用程序代码"]
User["非 root 用户:dify<br/>UID/GID:1001"]
Entrypoint["ENTRYPOINT:/bin/bash /entrypoint.sh"]
end
Base --> Packages
Packages --> PythonDeps
Base --> ProdRuntime
PythonDeps -. "复制 .venv" .-> CopyVenv
CopyVenv --> NLTKDownload
NLTKDownload --> TiktokenCache
TiktokenCache --> AppCode
AppCode --> User
User --> Entrypoint
阶段 1:基础镜像 - 使用 Python 3.12-slim 和 uv 包管理器建立基础环境 api/Dockerfile:2-10。全局安装 uv(版本 0.8.9)以实现快速依赖解析 api/Dockerfile:7-9。
阶段 2:依赖包 - 专门用于依赖编译。安装构建所需工具如 g++ 和数学库(libmpfr-dev、libmpc-dev),这些库是 gmpy2 等包所必需的 api/Dockerfile:17-22。命令 uv sync --frozen --no-dev 将生产依赖安装到 /app/api/.venv 的虚拟环境中,包括 providers/ 下的工作区成员 api/Dockerfile:25-28。
阶段 3:生产环境 - 最终运行时镜像。仅从 packages 阶段复制编译好的 Python 虚拟环境 api/Dockerfile:95-97。关键组件包括:
- Node.js 22:安装以支持 API 内的代码执行需求
api/Dockerfile:55-81。 - 系统工具:
fonts-noto-cjk用于 PDF 工具,media-types用于 MIME 类型猜测,libmagic1用于文件类型检测api/Dockerfile:86-91。 - NLTK 数据:预下载到
/usr/local/share/nltk_dataapi/Dockerfile:101-103。 - 非 root 用户:
dify用户(UID 1001)用于安全加固api/Dockerfile:54-60。
来源: api/Dockerfile:1-123
Web 多阶段构建流程
Web 镜像构建使用 node:22-alpine 基础镜像,并采用四阶段流程以优化 Next.js 独立输出。
graph TB
subgraph "阶段 1:基础镜像 [web/Dockerfile:2-17]"
WebBase["node:22-alpine<br/>corepack enable<br/>启用 pnpm"]
end
subgraph "阶段 2:依赖包 [web/Dockerfile:20-34]"
WebDeps["复制 package.json, pnpm-lock.yaml<br/>pnpm install --frozen-lockfile"]
end
subgraph "阶段 3:构建器 [web/Dockerfile:37-46]"
Build["WORKDIR /app/web<br/>pnpm build<br/>pnpm build:vinext"]
end
subgraph "阶段 4:生产环境 [web/Dockerfile:49-89]"
WebProd["非 root 用户:dify<br/>复制独立输出<br/>复制 public 和 static 资源"]
WebEntry["ENTRYPOINT:/bin/sh ./entrypoint.sh"]
end
WebBase --> WebDeps
WebDeps --> Build
Build --> WebProd
WebProd --> WebEntry
来源: web/Dockerfile:1-89
---
依赖管理与层优化
UV 包管理器(API)
API Dockerfile 使用 uv 实现高性能依赖解析 api/Dockerfile:7-9。构建过程利用 uv.lock 和 --frozen 标志,通过信任已检入的锁定文件来确保可重现的环境 api/Dockerfile:25-28。
PNPM 和 Corepack(Web)
Web 服务使用 pnpm 进行包管理,通过 corepack 启用 web/Dockerfile:12-13。它安装工作区依赖,包括 packages/ 目录中的依赖 web/Dockerfile:28-34。
层缓存策略
构建过程旨在最大化 Docker 层缓存。依赖清单文件(API 的 pyproject.toml、uv.lock;Web 的 package.json、pnpm-lock.yaml)在完整应用程序源代码之前被复制 api/Dockerfile:25-26、web/Dockerfile:24-27。这确保了耗时的依赖安装层仅在锁定文件发生变化时才失效。
来源: api/Dockerfile:7-28、web/Dockerfile:12-34
---
运行时优化:预热缓存
NLTK 数据预下载
API 镜像在构建期间下载 NLTK 数据集,以避免文档处理时的运行时延迟和连接问题:
RUN mkdir -p /usr/local/share/nltk_data \
&& NLTK_DATA=/usr/local/share/nltk_data python -c "import nltk; nltk.download('punkt'); nltk.download('averaged_perceptron_tagger'); nltk.download('stopwords')"
来源: api/Dockerfile:101-103
Tiktoken 编码缓存
API 镜像为 gpt2 模型预热 tiktoken 缓存,以消除 Token 计数任务中的首次使用延迟 api/Dockerfile:105-108。
---
安全加固:非 root 用户执行
API 和 Web 镜像均设计为以非 root 用户 dify(UID 1001)运行,以遵循最小权限原则。
| 特性 | API 实现 api/Dockerfile:54-60 | Web 实现 web/Dockerfile:68-72 |
|---|---|---|
| 用户创建 | groupadd -r -g 1001 dify && useradd -r -u 1001 -g 1001 | addgroup -S -g 1001 dify && adduser -S -u 1001 -G dify |
| 所有权 | chown -R dify:dify /app | chown -R dify:dify /app |
| Shell | /bin/bash | /bin/ash |
| 执行 | USER dify | USER dify |
来源: api/Dockerfile:54-121、web/Dockerfile:68-87
---
环境变量映射
构建过程注入默认环境变量,这些变量定义了应用程序的生产行为。
| 变量 | API 默认值 api/Dockerfile:33-39 | Web 默认值 web/Dockerfile:51-60 |
|---|---|---|
EDITION | SELF_HOSTED | SELF_HOSTED |
DEPLOY_ENV | PRODUCTION | PRODUCTION |
CONSOLE_API_URL | http://127.0.0.1:5001 | http://127.0.0.1:5001 |
APP_WEB_URL | http://127.0.0.1:3000 | 不适用 |
NODE_ENV | 不适用 | production |
这些默认值通常会在运行时通过 .env 文件或 Docker Compose 配置被覆盖 web/.env.example:1-10。
来源: api/Dockerfile:33-39、web/Dockerfile:51-60、web/.env.example:1-10
---
服务入口点
两个服务均使用入口点脚本来管理启动逻辑和环境变量注入。
API 入口点(/entrypoint.sh)
API 镜像入口点 api/Dockerfile:123 根据 MODE 环境变量(例如 api、worker、beat)促进不同服务的执行。它负责在启动 Python 应用程序之前初始化环境。
Web 入口点(./entrypoint.sh)
Web 镜像入口点 web/Dockerfile:89 处理 Next.js 独立服务器的启动。它还执行运行时环境变量注入,用于需要提供给客户端的变量,例如 TEXT_GENERATION_TIMEOUT_MS web/.env.example:42-43。
来源: api/Dockerfile:114-123、web/Dockerfile:82-89、web/.env.example:42-43