Dify二次开发构建api后端Docker离线镜像方案

核心思路

离线部署的核心是提前本地化所有依赖资源(系统 deb 包、Python 库、nltk/tiktoken 数据、基础镜像),通过 Docker 多阶段构建理念适配离线场景,将所有资源打包进镜像,彻底摆脱外网依赖。整体流程分为「离线资源准备」「Dockerfile 适配」「镜像构建」「离线部署」四大步骤,确保部署过程零网络请求。

一、离线资源准备(联网环境执行)

在有网络的机器上完成所有依赖资源的下载与打包,最终生成 offline-resources.tar.gz 离线资源包,传输至无网络虚拟机。

1.1 目录结构规划(提前创建)

plaintext

复制代码
dify-offline-build/
├── resources/
│   ├── base-image/       # 基础镜像存储目录
│   ├── debs/             # 系统deb包存储目录
│   └── data/             # 离线数据(nltk/tiktoken)
│       ├── nltk_data/
│       └── tiktoken_cache/
├── docker_requirements_final/  # Python离线依赖包
├── download-debs.sh      # deb包下载脚本
├── pyproject.toml        # Dify API源码中的依赖声明文件
├── uv.lock               # Dify API源码中的依赖锁文件
└── requirements.txt      # 导出的Python依赖清单

1.2 下载基础镜像

bash

运行

复制代码
# 拉取基础镜像
docker pull python:3.12-slim-bookworm

# 保存镜像为tar包(后续导入离线环境)
mkdir -p resources/base-image
docker save -o resources/base-image/python-3.12-slim-bookworm.tar python:3.12-slim-bookworm

1.3 下载系统 deb 包(编译 / 运行依赖)

创建并执行 deb 包下载脚本,通过 Docker 容器下载所需系统依赖:

bash

运行

复制代码
# 创建下载脚本
cat > download-debs.sh << 'EOF'
#!/bin/bash
set -e
# 确保deb存储目录存在
mkdir -p resources/debs && cd resources/debs

# 通过Python基础镜像下载deb包(使用阿里云源加速)
docker run --rm -v $(pwd):/tmp/debs python:3.12-slim-bookworm bash -c "
  sed -i 's@deb.debian.org@mirrors.aliyun.com@g' /etc/apt/sources.list.d/debian.sources && \
  apt-get update && \
  apt-get install -y --download-only \
    gcc g++ libc-dev libffi-dev libgmp-dev libmpfr-dev libmpc-dev \
    curl nodejs libgmp-dev libmpfr-dev libmpc-dev \
    expat libldap-2.5-0 perl libsqlite3-0 zlib1g \
    fonts-noto-cjk media-types libmagic1 && \
  cp /var/cache/apt/archives/*.deb /tmp/debs/
"

# 打包deb包(便于离线传输)
tar -czf debs.tar.gz ./*.deb
echo "✅ deb包下载完成,已打包为 debs.tar.gz"
EOF

# 赋予执行权限并运行
chmod +x download-debs.sh && ./download-debs.sh

1.4 下载 Python 依赖(项目核心依赖)

基于 Dify API 源码的依赖声明,下载所有 Python 包至离线目录:

bash

运行

复制代码
# 1. 创建干净的Python虚拟环境
python -m venv .venv
source .venv/bin/activate

# 2. 安装依赖管理工具uv(与原版Dockerfile一致)
pip install uv

# 3. 生成依赖锁文件(若源码中无uv.lock,需执行此步)
uv lock

# 4. 导出依赖清单(不含开发依赖)
uv export --locked > requirements.txt

# 5. 下载所有Python依赖到离线目录
mkdir -p docker_requirements_final
pip download -r requirements.txt -d docker_requirements_final

echo "✅ Python依赖下载完成,共 $(ls docker_requirements_final | wc -l) 个包"

1.5 下载离线数据(nltk/tiktoken)

bash

运行

复制代码
# 创建数据存储目录
mkdir -p resources/data/nltk_data resources/data/tiktoken_cache

# 下载nltk分词数据(通过Python脚本下载)
cat > download-nltk-data.py << 'EOF'
import nltk
nltk.download('punkt', download_dir='/tmp/nltk_data')
nltk.download('averaged_perceptron_tagger', download_dir='/tmp/nltk_data')
nltk.download('wordnet', download_dir='/tmp/nltk_data')
EOF

# 执行脚本并复制到资源目录
python download-nltk-data.py
cp -r /tmp/nltk_data/* resources/data/nltk_data/

# 下载tiktoken编码缓存(以gpt2为例,根据实际需求补充)
cat > download-tiktoken-cache.py << 'EOF'
import tiktoken
tokenizer = tiktoken.get_encoding("gpt2")
# 触发缓存下载
tokenizer.encode("test")
EOF

python download-tiktoken-cache.py
# 复制缓存文件(不同系统路径可能不同,需自行调整)
cp -r ~/.cache/tiktoken/* resources/data/tiktoken_cache/

echo "✅ 离线数据下载完成"

1.6 打包离线资源

将所有下载的资源打包,便于传输至无网络虚拟机:

bash

运行

复制代码
tar -czf offline-resources.tar.gz resources/ docker_requirements_final/ requirements.txt pyproject.toml uv.lock
echo "✅ 所有离线资源打包完成:offline-resources.tar.gz"

二、离线环境准备(无网络虚拟机执行)

2.1 传输并解压离线资源

offline-resources.tar.gz 传输至无网络虚拟机的 /home/Documents/dify-offline-build/ 目录,执行解压:

bash

运行

复制代码
# 创建工作目录
mkdir -p /home/Documents/dify-offline-build
cd /home/Documents/dify-offline-build

# 解压资源包
tar -xzf offline-resources.tar.gz
echo "✅ 离线资源解压完成"

2.2 导入基础镜像

bash

运行

复制代码
# 导入Python基础镜像
docker load -i resources/base-image/python-3.12-slim-bookworm.tar

# 验证镜像导入成功
docker images | grep python:3.12-slim-bookworm
echo "✅ 基础镜像导入完成"

2.3 准备 Dify API 源码

将 Dify 1.8.1 源码的 api 目录复制至当前工作目录(确保包含 app.pyentrypoint.sh 等核心文件):

bash

运行

复制代码
# 假设源码已传输至虚拟机,复制API目录
cp -r /home/Documents/dify/dify1.8.1/api/* /home/Documents/dify-offline-build/
echo "✅ Dify API源码准备完成"

三、编写离线 Dockerfile(Dockerfile.offline)

/home/Documents/dify-offline-build/ 目录创建 Dockerfile.offline,内容如下:

dockerfile

复制代码
FROM python:3.12-slim-bookworm

# 环境变量配置
ENV LC_ALL=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
ENV DIFY_PROFILE=prod
ENV NLTK_DATA=/app/api/nltk_data
ENV TIKTOKEN_CACHE_DIR=/app/api/tiktoken_cache

# 设置工作目录
WORKDIR /app/api

# ---------------------------
# 步骤1:安装离线deb包(系统依赖)
# ---------------------------
COPY ./resources/debs/debs.tar.gz /tmp/
RUN mkdir -p /tmp/debs && \
    tar -xzf /tmp/debs.tar.gz -C /tmp/debs && \
    # 安装deb包,自动解决依赖冲突
    dpkg -i /tmp/debs/*.deb || apt -f install -y --no-install-recommends && \
    # 清理缓存,减小镜像体积
    rm -rf /tmp/debs /tmp/debs.tar.gz /var/lib/apt/lists/*

# ---------------------------
# 步骤2:安装离线Python依赖
# ---------------------------
COPY ./docker_requirements_final /tmp/packages
COPY ./requirements.txt /tmp/
RUN python -m pip install --no-index --find-links=/tmp/packages /tmp/packages/* && \
    # 清理离线包
    rm -rf /tmp/packages /tmp/requirements.txt && \
    # 验证依赖安装
    pip list | grep -E "flask|celery|docker" || echo "⚠️  部分核心依赖未安装"

# ---------------------------
# 步骤3:复制离线数据(nltk/tiktoken)
# ---------------------------
COPY ./resources/data/nltk_data /app/api/nltk_data
COPY ./resources/data/tiktoken_cache /app/api/tiktoken_cache
RUN chmod -R 755 /app/api/nltk_data /app/api/tiktoken_cache

# ---------------------------
# 步骤4:复制项目源码
# ---------------------------
COPY . /app/api
RUN chmod +x /app/api/entrypoint.sh

# ---------------------------
# 步骤5:暴露端口并设置启动命令
# ---------------------------
EXPOSE 5001
CMD ["sh", "/app/api/entrypoint.sh"]

四、构建离线镜像

/home/Documents/dify-offline-build/ 目录执行镜像构建命令:

bash

运行

复制代码
# 无缓存构建,确保资源加载最新
docker build --no-cache -f Dockerfile.offline -t dify-api:1.8.1-offline .

# 验证镜像构建成功
docker images | grep dify-api:1.8.1-offline
echo "✅ Dify API离线镜像构建完成"

五、离线部署 Dify 服务

5.1 修改 docker-compose.yml

进入 Dify 的 Docker Compose 配置目录,修改 API 服务的镜像名称为离线构建的镜像:

bash

运行

复制代码
cd /home/Documents/dify/dify1.8.1/dify/docker
sudo nano docker-compose.yml

修改核心配置(仅展示 API 服务部分,其他服务配置保持不变):

yaml

复制代码
services:
  api:
    image: dify-api:1.8.1-offline  # 替换为离线构建的镜像
    restart: always
    ports:
      - "5001:5001"
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/dify
      - REDIS_URL=redis://redis:6379/0
    volumes:
      - ./data/api:/app/api/data
    depends_on:
      - db
      - redis

5.2 启动 Dify 服务

bash

运行

复制代码
# 后台启动所有服务(使用Docker内置Compose,无横杠)
sudo docker compose up -d

# 查看服务启动状态
sudo docker compose ps

# 查看API服务日志(验证无报错)
sudo docker compose logs -f api

5.3 验证部署成功

bash

运行

复制代码
# 测试API接口是否可用(本地访问)
curl http://localhost:5001/health
# 预期返回:{"status":"healthy"}

echo "✅ Dify 1.8.1 离线部署完成!"
相关推荐
随风一样自由44 分钟前
目前的AI大模型工具有哪些?具体都有哪些领域的应用?简单分析一下
人工智能·ai·语言模型
看今朝·1 小时前
【软件工程3.0】智能时代企业新型生产关系:人机协同的系统性变革
人工智能·大模型·软件工程·多模型协同·目标优化
赵得C1 小时前
昇腾应用使能套件:华为AI生态的“技术桥梁”与落地实践
人工智能·华为
bryant_meng1 小时前
【PSMNet】《Pramid Stereo Matching Network》
人工智能·深度学习·计算机视觉·stereo matching·psmnet
初圣魔门首席弟子1 小时前
网络编程所有通信方式总结 C++ 实现模板(基于 C++11+)
运维·服务器
a***13141 小时前
【玩转全栈】----Django制作部门管理页面
后端·python·django
a***81391 小时前
【Go】Go语言基础学习(Go安装配置、基础语法)
服务器·学习·golang
我很哇塞耶1 小时前
从 “检索知识” 到 “会用知识”:西安交大 + 华为 2025 EMNLP 新方案RAG+
人工智能·ai·大模型·rag·检索增强生成
AI科技星1 小时前
加速正电荷产生的电场、引力场与磁场变化率方向关系的数学求导验证——基于张祥前统一场论核心方程
数据结构·人工智能·经验分享·算法·机器学习·计算机视觉