1. 项目概述一次典型的信创环境攻坚最近在帮一个金融客户做AI应用平台的国产化迁移核心任务是把Dify这个开源的LLM应用开发框架从x86环境完整地搬到飞腾FT-2000/64CPU和银河麒麟V10 SP3操作系统的组合上。客户的要求很明确零修改源码。这意味着我们不能动Dify项目本身的任何一行Python或前端代码所有适配工作必须通过环境配置、依赖替换和外围集成来解决。这听起来像是个“螺蛳壳里做道场”的精细活但恰恰是当前信创项目中最常见、也最考验工程能力的场景——你没法要求所有开源软件都为你量身定做ARM版本但业务又必须跑起来。Dify本身是一个集成了LLM编排、RAG知识库、工作流和Agent能力的平台后端是PythonFastAPI前端是React依赖Redis、PostgreSQL等组件。在x86的Linux上用Docker Compose一键部署是主流。但在飞腾麒麟的ARMv8环境中这条路直接走不通Docker Hub上官方镜像都是x86_64架构的。所以整个适配的核心就变成了如何在纯ARM环境中从源码开始手动构建出Dify及其所有依赖的运行环境并确保其功能完整、性能达标同时集成国密算法和国产中间件。这次适配的最终目标是形成一个可复现的、标准化的部署流程不仅让Dify跑起来还要实现国密SM2证书的HTTPS访问与用户登录并且将Dify作为Web应用部署到客户指定的国产应用服务器——东方通TongWeb上。整个过程涉及操作系统层、编译工具链、Python生态、前端构建、数据库、缓存以及应用服务器多个层面的适配算是一次对信创全栈技术能力的实战检验。2. 环境准备与基础依赖编译2.1 银河麒麟V10 SP3系统初始化拿到一台搭载飞腾FT-2000/64处理器的服务器预装了银河麒麟高级服务器操作系统V10 SP3。第一步不是急着装软件而是做好系统层面的标准化配置这能为后续编译减少大量麻烦。首先确认系统架构和版本uname -m # 输出aarch64 cat /etc/kylin-release # 输出Kylin Linux Advanced Server release V10 (Tercel)确保系统已更新到最新SP补丁。接着配置国内的信创软件源或麒麟官方源这对于在离线或受限网络环境下获取ARM架构的软件包至关重要。银河麒麟的软件仓库通常已经包含了针对飞腾优化的基础库。安装最基础的开发工具链yum groupinstall -y Development Tools yum install -y python3-devel python3-pip openldap-devel openssl-devel bzip2-devel libffi-devel sqlite-devel gcc-c make cmake这里特别注意要安装python3-devel和openldap-devel因为Dify的Python依赖如ldap3在编译时可能需要链接这些库。另一个关键点是Python环境的管理。我强烈建议使用pyenv配合virtualenv而不是直接使用系统Python。原因有三1可以灵活选择Python版本Dify推荐3.92避免污染系统Python环境3便于依赖隔离和问题排查。在ARM架构上从源码编译Python时需要先安装一些额外的依赖yum install -y zlib-devel readline-devel libsqlite3x-devel tk-devel gdbm-devel libuuid-devel xz-devel然后通过pyenv安装指定版本的Python这个过程在飞腾CPU上编译时间会稍长属于正常现象。2.2 关键依赖的手动编译以Redis和PostgreSQL为例Dify依赖Redis和PostgreSQL。虽然银河麒麟的软件源可能提供ARM版本的安装包但为了追求版本的完全可控和最佳性能我选择了手动编译。Redis编译从Redis官网下载源码包如6.2.x版本。在ARM平台编译Redis通常很顺利tar xzf redis-6.2.13.tar.gz cd redis-6.2.13 make -j$(nproc) make install-j$(nproc)参数能利用飞腾FT-2000的多核优势加速编译。编译完成后需要重点调整的是redis.conf配置文件将bind 127.0.0.1改为bind 0.0.0.0或服务器内网IP以便后端服务连接。设置requirepass一个强密码这是生产环境的基本安全要求。根据服务器内存大小合理设置maxmemory和淘汰策略如allkeys-lru。将daemonize设置为yes以便以守护进程方式运行。PostgreSQL编译PostgreSQL的编译配置选项更多对性能影响也更大。以PostgreSQL 15为例tar xjf postgresql-15.6.tar.bz2 cd postgresql-15.6 ./configure --prefix/usr/local/pgsql-15 --with-openssl make -j$(nproc) make install--with-openssl确保支持SSL连接。编译安装后需要初始化数据库集群、启动服务并创建Dify所需的数据库和用户。这里的一个经验是在postgresql.conf中针对飞腾架构和业务特点进行调整例如shared_buffers通常设置为系统内存的25%、work_mem等参数需要在服务器内存容量和并发连接数之间取得平衡。注意手动编译安装的服务需要自行编写systemd服务单元文件.service文件并配置开机自启这是保证服务稳定性的重要一步不要依赖手动启动。3. Dify v1.12.3源码适配与构建3.1 后端Python环境搭建与依赖安装获取Dify v1.12.3的源码解压后进入后端目录。首先创建独立的虚拟环境cd dify/backend python3 -m venv venv source venv/bin/activate接下来是最关键也最容易出错的环节安装Python依赖。requirements.txt文件里列出的包大部分都有预编译的ARM版wheel可以通过pip直接从PyPI或国内镜像拉取。但总有那么几个包在特定时期可能没有提供aarch64的二进制轮子这时pip会尝试从源码编译。常见编译问题与解决密码学相关库如cryptography这类包编译需要Rust工具链。如果服务器没有Rust会报错。解决方案是提前安装Rustcurl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh然后将其加入PATH。或者更简单的方法是寻找提供ARM64 wheel的较新版本或通过系统包管理器安装如yum install -y python3-cryptography但要注意版本兼容性。Psycopg2PostgreSQL适配器如果未找到预编译包需要系统已安装postgresql-devel开发包否则编译会失败。我们在2.2节已经安装了。UVLoop这是一个高性能事件循环库其源码编译对Linux内核版本和glibc有一定要求。银河麒麟V10 SP3的内核版本通常足够。如果编译失败可以尝试降级到一个已知稳定的版本或者在requirements.txt中暂时注释掉如果Dify未强制依赖用标准的asyncio替代性能会有损失。一个稳妥的安装策略是分步进行并记录日志以便排查pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 21 | tee install.log如果某个包反复编译失败可以尝试单独安装并指定版本或使用--no-binary选项强制从源码编译同时观察错误信息。大部分情况下飞腾ARM64平台与通用的aarch64架构是兼容的编译问题多源于缺失系统级开发库。3.2 前端资源构建与ARM兼容性处理进入前端目录dify/web。前端构建依赖Node.js和npm/yarn。需要从Node官网下载ARM64版本的二进制包如Node.js 18.x LTS并安装。安装依赖和构建npm install --registryhttps://registry.npmmirror.com npm run build前端构建过程一般比较顺利因为Node.js生态的跨平台性很好。主要挑战可能出现在内存不足构建React应用尤其是生产环境构建时可能需要较大内存。如果服务器内存紧张可能会因JavaScript堆内存溢出FATAL ERROR: Reached heap limit Allocation failed而失败。解决方法是通过环境变量增加Node.js内存限制export NODE_OPTIONS--max-old-space-size4096将内存限制提高到4GB。特定Native模块极少数前端依赖可能包含本地绑定native bindings需要编译。这要求系统有g和make我们在基础环境中已经安装。构建完成后会在dist目录生成静态文件。我们需要将这些文件交给后续的TongWeb应用服务器来托管。因此构建完成后可以先将dist目录的内容打包备用。3.3 配置文件详解与国产化调整Dify的配置主要通过后端目录下的.env文件和环境变量管理。在国产化环境中有几处配置必须仔细核对1. 数据库与缓存连接DB_HOSTlocalhost DB_PORT5432 DB_USERdifyuser DB_PASSWORDYourStrongPassword123! DB_NAMEdify REDIS_HOSTlocalhost REDIS_PORT6379 REDIS_PASSWORDYourRedisPassword确保这里的DB_HOST和REDIS_HOST指向我们手动编译安装的服务地址。如果服务不在本机需填写正确的内网IP。密码务必强密码。2. 模型与向量库配置这是AI能力的核心。在信创内网通常无法直接访问OpenAI等海外API。需要配置本地部署的大模型和向量模型。LLM_MODELlocal # 或具体模型标识 MODEL_PROVIDERlocalai # 使用本地推理框架 LOCALAI_API_BASEhttp://localhost:8080/v1 EMBEDDING_MODEL_PROVIDERlocal EMBEDDING_MODEL_NAMEBAAI/bge-large-zh-v1.5 # 一个优秀的中文向量模型这意味着你还需要在环境中部署一个本地推理服务如LocalAI、Ollama或直接部署vLLM等并将对应的国产或开源大模型如ChatGLM3、Qwen、InternLM等加载进去。向量模型同样需要本地部署例如使用FlagEmbedding库。这些模型的ARM兼容性需要单独验证通常PyTorch等框架已提供ARM支持。3. 文件存储与外部服务如果涉及文件上传需要配置存储。在信创环境可能使用本地存储或兼容S3协议的国产对象存储。STORAGE_TYPElocal FILE_UPLOAD_PATH/data/dify/storage将路径设置为一个容量充足、有写权限的目录。4. 国密SM2算法集成与HTTPS配置4.1 国密SSL证书申请与转换在金融等对安全有严格要求的行业采用国密算法SM2进行传输加密是硬性要求。我们需要为Dify的访问域名或IP签发国密SSL证书。通常流程是向合规的CA机构申请SM2证书你会得到两个关键文件.sign.crt签名证书和.enc.crt加密证书以及对应的私钥文件.key。然而Nginx、TongWeb等主流Web服务器通常期望的是PEM格式的证书和私钥。你需要将得到的证书和私钥转换为PEM格式。使用OpenSSL命令确保系统OpenSSL支持国密银河麒麟V10通常已集成# 假设证书为SM2格式可能需要使用gmssl国密版openssl gmssl ecparam -name sm2p256v1 -genkey -out server.key # 将得到的签名证书和加密证书合并具体顺序可能根据CA要求 cat your_domain.sign.crt your_domain.enc.crt server.crt重要提示国密证书的申请、格式转换和部署有严格规范务必遵循你们单位安全部门或CA机构提供的具体指南。私钥文件.key必须严格保密权限设置为600。4.2 TongWeb应用服务器配置与部署东方通TongWeb是一款主流的国产Java应用服务器。我们的目标是将Dify的后端API服务Python FastAPI和前端静态文件整合部署到TongWeb中。这里有两种思路方案一前后端分离部署推荐前端将dify/web/dist目录下的所有静态文件直接放置在TongWeb的某个Web应用目录下例如$TONGWEB_HOME/webapps/ROOT或者创建一个新的WAR包仅包含静态资源进行部署。通过TongWeb配置静态资源服务。后端将Dify后端作为一个独立的服务进程启动。这需要编写一个启动脚本激活Python虚拟环境然后使用uvicorn或gunicorn启动FastAPI应用并绑定到某个本地端口如127.0.0.1:5001。方案二整合部署更复杂尝试通过TongWeb的CGI、WSGI或反向代理功能来运行Python后端。对于FastAPI应用更可行的方式是使用ASGI协议。可以寻找或开发一个支持ASGI的Java Servlet容器桥接组件但这超出了常规部署范畴复杂度高。因此方案一是更务实的选择。配置TongWeb的反向代理功能将API请求转发到后端的Python服务。TongWeb反向代理配置示例在server.xml或管理控制台配置假设TongWeb监听8080端口Dify后端运行在5001端口。!-- 在TongWeb的配置中添加一个反向代理规则 -- !-- 将 /api/v1/* 的请求转发到后端服务 -- Valve classNameorg.apache.catalina.valves.rewrite.RewriteValve / Context path/ Valve classNameorg.apache.catalina.valves.rewrite.RewriteValve RewriteRule ^/api/v1/(.*)$ http://localhost:5001/api/v1/$1 [P] /Valve /Context同时需要修改Dify前端构建时产生的配置文件将API请求的基地址指向TongWeb的地址如/api/v1而不是直接访问后端端口。这通常需要在前端构建时注入环境变量或修改相关配置。4.3 HTTPS与国密双栈配置为了兼容不支持国密的浏览器同时满足国密要求可以配置国密与非国密双栈。即TongWeb同时监听两个端口一个使用国密SSL证书另一个使用国际算法RSA/ECC证书。在TongWeb的server.xml中可以配置多个Connector!-- 国际算法 HTTPS端口 8443 -- Connector port8443 protocolHTTP/1.1 SSLEnabledtrue maxThreads150 schemehttps securetrue keystoreFile/path/to/rsa_keystore.jks keystorePassyour_password clientAuthfalse sslProtocolTLS/ !-- 国密 HTTPS端口 9443 -- Connector port9443 protocolHTTP/1.1 SSLEnabledtrue maxThreads150 schemehttps securetrue sslImplementationNameorg.apache.tomcat.util.net.jsse.JSSEImplementation !-- 此处需使用支持国密的JSSE实现并指定国密证书和密码套件 -- !-- 具体配置参数需参考TongWeb国密支持文档 -- /用户或内部系统可以根据能力选择访问端口。Dify后端服务本身localhost:5001可以不开启HTTPS由TongWeb负责对外HTTPS终结和反向代理。5. 全流程集成与验证测试5.1 服务启动与初始化按照以下顺序启动所有服务启动PostgreSQLsystemctl start postgresql-15并确保数据库和用户已创建。启动Redissystemctl start redis。启动Dify后端进入后端虚拟环境执行启动命令。生产环境建议使用进程管理器如supervisor或systemd。cd /opt/dify/backend source venv/bin/activate # 使用gunicorn多进程性能更好 gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 127.0.0.1:5001 app:app --timeout 300-w 4指定工作进程数可根据飞腾CPU核心数调整。启动TongWeb通过$TONGWEB_HOME/bin/startup.sh启动。前端服务静态文件已由TongWeb托管无需单独启动。服务启动后首先访问TongWeb的国密HTTPS端口如https://your-server:9443应该能看到Dify的登录界面。如果出现空白页或JS错误检查浏览器控制台很可能是前端资源路径错误或API代理未生效。5.2 功能验证清单进行系统性的功能测试确保零修改源码下的所有核心功能正常测试模块测试项预期结果问题排查方向基础访问通过国密HTTPS访问首页正常加载登录页检查TongWeb国密Connector配置、证书、防火墙用户认证使用SM2证书双向认证如配置或账号密码登录登录成功进入控制台检查后端服务日志确认登录API (/api/v1/login) 被正确代理和响应应用创建创建新的文本生成应用创建成功可进入编排界面检查PostgreSQL连接确认相关表创建无误模型推理在应用中使用配置的本地模型提问能正常返回回答无超时或错误检查LOCALAI_API_BASE配置确认本地模型服务已启动且网络可达查看模型服务日志知识库创建知识库上传文档TXT/PDF进行问答能成功解析文档并能基于文档内容回答检查向量模型服务确认Embedding接口正常检查文件上传路径权限工作流创建一个包含条件判断、API调用的简单工作流并执行工作流能按设计执行得到预期结果检查工作流各节点配置特别是自定义API节点地址是否可访问系统设置修改系统设置如邮箱配置修改成功并保存检查数据库更新操作5.3 性能调优与监控建议在飞腾ARM平台上性能表现可能与x86有差异需要进行针对性观察和调优CPU与内存监控使用top、htop或vmstat监控gunicorn工作进程、PostgreSQL、Redis以及本地模型服务的CPU和内存占用。飞腾FT-2000/64在多核并发处理上表现良好但单核频率可能不如同代x86因此需要关注单线程密集型任务如模型推理中的一个请求的延迟。数据库调优关注PostgreSQL在ARM下的表现。可以调整shared_buffers、effective_cache_size、work_mem等参数。使用pg_stat_statements扩展找出慢查询。缓存优化确保Redis高效使用。监控内存使用率避免交换swapping。对于频繁读取的配置信息考虑利用Redis缓存。模型服务优化本地模型推理是性能瓶颈。如果使用LocalAI可以调整其并发参数。考虑使用vLLM这类高性能推理框架并确认其ARM版本兼容性。对于中文场景选择量化后的模型能显著降低内存占用和提升推理速度。网络与I/O确保服务器有足够的网络带宽特别是如果模型服务与Dify不在同一主机。文件上传下载的磁盘I/O性能也需要关注。6. 踩坑实录与经验总结6.1 编译与依赖问题Python包cryptography编译失败这是最经典的坑。错误信息通常指向缺少Rust。在离线环境提前下载好对应版本的Rust离线安装包和cryptography的源码包手动编译安装。或者如果环境允许直接使用系统包管理器提供的python3-cryptography。Node.js前端构建内存溢出在内存有限的虚拟机或容器中构建前端时频繁遇到。除了增加NODE_OPTIONS内存限制还可以尝试在构建命令中增加--max_old_space_size参数或者使用npm run build:prod如果存在可能比开发构建更优化内存使用。终极方案是找一台内存更大的机器构建然后将dist产物拷贝过来。系统库版本冲突手动编译的软件如PostgreSQL 15可能依赖新版的系统库如libreadline而麒麟系统自带的版本较旧。解决方法是在编译时指定使用自带的库路径--with-libraries或者谨慎地升级系统库需评估兼容性风险。6.2 配置与集成问题前端请求404API路径错误这是前后端分离部署最常见的错误。现象是页面能打开但所有API调用失败。检查1) 前端构建时配置的API_BASE_URL是否正确指向了TongWeb的反向代理路径如/api2) TongWeb中的反向代理规则是否正确匹配了前端请求的URL模式。国密证书浏览器不支持部分主流浏览器可能不完全支持国密SSL。测试时确保使用支持国密的浏览器如360安全浏览器国密版、麒麟桌面系统自带浏览器等。双栈配置就是为了解决这个兼容性问题。TongWeb反向代理导致WebSocket失败Dify的实时通信可能使用WebSocket。需要确保TongWeb的反向代理配置支持WebSocket协议升级。在Rewrite规则或代理配置中需要包含对Upgrade和Connection头的处理。时区与时间问题确保所有服务器数据库、应用服务器、后端服务使用统一的时区如Asia/Shanghai。否则可能导致日志时间错乱、定时任务执行异常等问题。在银河麒麟中使用timedatectl set-timezone Asia/Shanghai设置。6.3 安全加固建议最小权限原则为PostgreSQL、Redis创建专属的低权限用户运行服务不要使用root。Dify的后端进程也应用非root用户运行。网络隔离将Dify后端服务5001端口绑定在127.0.0.1仅允许TongWeb本机访问。通过TongWeb对外暴露HTTPS端口利用其安全特性。定期更新与漏洞扫描关注Dify官方发布的安全更新。虽然我们未修改源码但仍需及时将版本更新到修复了安全漏洞的Release。对服务器操作系统、数据库、中间件进行定期的安全漏洞扫描。审计日志开启Dify的操作日志功能并配置TongWeb的访问日志。定期审查日志发现异常访问行为。整个适配过程最深的体会是信创迁移三分在技术七分在耐心和细致。从一个个依赖包的编译到每一项服务的配置再到最后的联调测试任何一个微小的环节出错都可能导致前功尽弃。做好详细的部署文档和操作记录形成标准化的操作手册对于后续的批量部署和运维至关重要。这次在飞腾FT-2000/银河麒麟V10 SP3上成功跑通Dify全流程证明了基于主流开源软件构建的复杂应用是可以通过细致的环境适配在国产化平台上稳定运行的。