qKnow本地部署实战:MySQL+Neo4j+DeepKE+Gradio四层架构详解 📅 2026/7/16 11:53:44 1. 项目概述qKnow 是什么为什么值得本地部署qKnow 是一个面向知识图谱构建与智能问答的开源项目核心定位不是通用大模型前端而是聚焦在“结构化知识驱动的深度推理”这一细分场景。它把 DeepKE 这类实体识别与关系抽取模型、Neo4j 图数据库、MySQL 关系型存储以及 Gradio 快速界面封装能力拧成一股绳——用 MySQL 存原始文本、标注数据和元信息用 Neo4j 存实体、关系、属性构成的知识网络再让 DeepKE 在后台持续消化新文档自动补全图谱节点与边。整个流程闭环跑通后你输入一句“华为2023年收购了哪家芯片设计公司”系统不是靠大模型瞎猜而是先在 Neo4j 里查“华为”节点的“收购”关系边再顺着边找到目标公司节点最后从 MySQL 里捞出该公司的成立时间、主营业务等补充字段组合成有依据、可追溯、带来源的精准答案。这恰恰解释了为什么“本地部署”是 qKnow 的刚需。它不像 ChatGPT 那样开个网页就能用它的价值藏在数据闭环里你的行业报告、内部手册、专利文件、会议纪要——这些敏感、高价值、格式杂乱的私有数据绝不可能上传到任何公有云 API。而 Docker Compose 正是实现这种闭环最轻量、最可控的方式。它不依赖 Kubernetes 的复杂编排也不需要手动逐个拉镜像、配端口、挂卷、写启动脚本你只需要一个docker-compose.yml文件把 MySQL、Neo4j、qKnow 后端服务、Gradio 前端四者声明为“同属一个应用”Compose 就会自动处理网络互通、依赖顺序比如必须等 MySQL 初始化完再启动 qKnow、卷挂载确保数据库文件不随容器销毁而丢失——整套环境在一台 Ubuntu 笔记本上 5 分钟内就能跑起来换台机器复制粘贴再docker compose up -d就能复现这才是工程落地的真实节奏。我第一次部署时就踩在了“想当然”的坑里直接docker run单独启 Neo4j再docker run单独启 MySQL结果 qKnow 启动报错连不上数据库。查日志才发现两个容器默认在不同网络下IP 地址根本 ping 不通。后来才明白Docker Compose 的本质不是“多个容器的快捷启动器”而是“定义一个完整应用拓扑的 DSL”。它强制你以“服务”为单位思考mysql是一个服务neo4j是另一个服务qknow-api是第三个服务它们之间通过服务名如mysql:3306而非 IP 直接通信。这个抽象层看似简单实则屏蔽了大量底层网络配置的噪音让开发者能真正聚焦在业务逻辑本身。所以当你看到热搜词里反复出现docker compose restart always、docker compose ps no configuration file provided背后反映的其实是大量用户在从“单容器实验”迈向“多服务协同”的认知跃迁过程——而这正是 qKnow 本地部署的第一道门槛也是最关键的底层逻辑。2. 整体架构设计与技术选型深挖2.1 四层服务协同为什么是 MySQL Neo4j DeepKE Gradio 这个组合qKnow 的架构不是拍脑袋定的而是对知识图谱构建全流程做了一次“职责切分”。我把这套组合拆成四层来看每一层都解决一个不可替代的问题第一层MySQL —— 做“原始档案馆”它不存图谱只存三类东西一是原始文档PDF/Word/HTML 的文本切片二是人工标注的样本比如某段话里“苹果”是公司还是水果三是系统元数据任务执行日志、模型版本、用户操作记录。选择 MySQL 而非 PostgreSQL核心在于成熟度与生态所有 Python 数据处理库pandas、sqlalchemy对 MySQL 的支持最稳Docker 官方镜像更新最及时且mysqldump备份恢复命令十几年没变过运维零学习成本。更重要的是qKnow 的业务逻辑里几乎没有复杂的 JSON 查询或全文检索需求MySQL 的 ACID 事务足以保证标注数据的一致性——比如你标记一段文本为“正样本”这个操作必须和它关联的文档 ID、标注人 ID 一起写入不能丢一个。这点上MySQL 比轻量级 SQLite 更可靠比重型 PostgreSQL 更轻快。第二层Neo4j —— 做“关系引擎室”这是 qKnow 的心脏。DeepKE 抽出来的“张三-任职于-华为”、“华为-收购-昇腾”这类三元组必须存在图数据库里才能发挥“路径查询”的威力。举个实际例子你想查“哪些公司被华为收购后又被其他公司收购”在 MySQL 里得写三层 JOIN性能崩盘在 Neo4j 里就是一句 CypherMATCH (a:Company)-[:ACQUIRED]-(b:Company)-[:ACQUIRED]-(c:Company) RETURN a.name, b.name, c.name。Neo4j 的索引机制如:Company(name)让节点查找是 O(1)关系遍历是 O(1)这才是图谱查询毫秒级响应的物理基础。至于为什么不用 Nebula 或 JanusGraph因为 qKnow 的官方文档、示例脚本、Docker 配置全部围绕 Neo4j 展开社区教程比如“neo4j安装与配置”“neo4j菜鸟教程”铺天盖地新手遇到问题搜关键词就能找到答案这是工程选型里最朴素也最硬核的考量。第三层DeepKE —— 做“知识炼金术士”它不是大语言模型而是一个专注 NLP 底层任务的 PyTorch 框架特别擅长从非结构化文本里“抠”出实体和关系。qKnow 用它来干两件事一是初始化图谱——把历史文档批量喂给 DeepKE生成第一批三元组导入 Neo4j二是增量更新——当新文档入库自动触发 DeepKE 再次分析把新发现的关系实时追加进图。这里的关键是DeepKE 模型可以离线训练、本地加载完全不依赖外部 API。你甚至可以把公司年报 PDF 放进data/input/目录改一行配置文件里的路径python run_deepke.py就能跑出结果。这种“数据不出门、模型不联网”的特性是金融、医疗、政企客户敢用 qKnow 的前提。第四层Gradio —— 做“交互前台”它不负责业务逻辑只负责把后端能力“翻译”成普通人能用的界面。qKnow 的 Gradio 界面通常只有三个输入框问题文本、知识图谱查询模式关键词搜索 / 关系路径 / 实体详情、返回结果条数。点提交后前端调用qknow-api的/ask接口后端去 Neo4j 查图、去 MySQL 补充字段、再把结构化结果渲染成表格或关系图。选择 Gradio 而非 Streamlit 或 FastAPI 自建页面就图一个“快”5 行代码就能搭出带按钮、滑块、文件上传的 UI且所有组件都内置了类型校验和错误提示。我试过把 Gradio 替换成 Vue 前端光是跨域请求配置和 Token 管理就折腾了两天而 Gradio 用auth(user, pass)一行就加上了基础认证——对于一个以快速验证为核心目标的本地知识库项目这种“够用就好”的务实主义才是真正的生产力。2.2 Docker Compose 的不可替代性它到底在管什么很多人把docker compose当成docker run的批量版这是最大的误解。Docker Compose 的核心价值在于它管理的是“服务间的契约”而不是“容器的生命周期”。我们拿 qKnow 的docker-compose.yml里最关键的三段配置来解剖services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: qknow_db volumes: - ./mysql-data:/var/lib/mysql restart: unless-stopped neo4j: image: neo4j:5.16 environment: NEO4J_AUTH: neo4j/password NEO4J_apoc_export_file_enabled: true NEO4J_apoc_import_file_enabled: true volumes: - ./neo4j-data:/data - ./neo4j-plugins:/plugins ports: - 7474:7474 # Browser - 7687:7687 # Bolt restart: unless-stopped qknow-api: build: ./backend environment: MYSQL_HOST: mysql MYSQL_PORT: 3306 NEO4J_URI: bolt://neo4j:7687 NEO4J_USER: neo4j NEO4J_PASSWORD: password depends_on: - mysql - neo4j restart: unless-stopped这段代码里藏着三个关键设计决策第一volumes挂载是数据持久化的命脉./mysql-data:/var/lib/mysql这行意味着宿主机当前目录下的mysql-data文件夹会被映射为容器内 MySQL 的数据目录。这样即使你docker compose down删除容器mysql-data文件夹里的.ibd文件还在下次up时 MySQL 会自动读取旧数据继续工作。同理./neo4j-data:/data保证了图谱不会每次重启就清空。很多新手部署失败90% 是因为漏了volumes或者路径写错比如写成./data/mysql但宿主机根本没有这个目录导致容器一删几个月构建的图谱全没了。这不是 bug是设计——Docker 默认一切皆临时你必须显式声明“这里的数据我要留着”。第二depends_on不是“等待启动完成”而是“声明依赖顺序”qknow-api依赖mysql和neo4jCompose 会确保mysql和neo4j容器先create并start但不会等 MySQL 初始化完数据库、也不会等 Neo4j 加载完插件。这就是为什么你常看到qknow-api启动时报Connection refused。解决方案不是改depends_on而是在qknow-api的启动脚本里加健康检查重试逻辑比如用wait-for-it.sh脚本循环检测mysql:3306是否可连或者在应用代码里捕获数据库连接异常并重试。depends_on的真实作用是让qknow-api的MYSQL_HOST环境变量能解析到mysql这个 DNS 名——因为 Compose 会为每个服务名自动创建一个内部 DNS 记录mysql这个名字在容器网络里就指向 MySQL 容器的 IP。没有depends_onqknow-api可能因 DNS 缓存未生效而解析失败。第三restart: unless-stopped是生产可用的底线它告诉 Docker“除非我手动docker compose stop否则容器崩溃后必须自动重启”。对比always连手动 stop 都重启和no崩溃就躺平unless-stopped是最平衡的选择。它既避免了服务意外退出导致知识库不可用比如内存溢出 kill 了 Neo4j又保留了人工干预的权力。我见过太多本地部署案例因为用了restart: no某天笔记本休眠唤醒后 Neo4j 没起来整个 qKnow 就成了摆设而用户根本不知道发生了什么——直到他打开docker compose ps看到状态是Exited。2.3 配置文件的精妙分层如何让一套 YAML 适配不同环境一个健壮的 qKnow 部署绝不会只有一份docker-compose.yml。我推荐采用三文件策略这是从几十次跨团队部署中沉淀下来的最小可行方案docker-compose.base.yml存放所有服务的共性配置比如镜像版本、基础环境变量、卷挂载路径、端口映射。这部分是“不变的骨架”。docker-compose.dev.yml开发环境专用比如开启 Gradio 的debugTrue模式挂载源码目录实现热重载volumes: - ./backend:/app暴露更多调试端口如 Python 的ptvsd。docker-compose.prod.yml生产环境专用比如关闭所有调试接口设置restart: unless-stopped启用资源限制mem_limit: 2g配置 HTTPS 反向代理通过 Nginx 容器。最终启动命令是docker compose -f docker-compose.base.yml -f docker-compose.prod.yml up -d这种分层的好处是“一次编写多处复用”。比如你要在 Ubuntu 服务器上部署就用prod.yml要在 Windows 开发机上调试后端逻辑就用dev.yml连base.yml都不用碰。更关键的是它天然规避了“配置污染”——你不会在生产配置里不小心留下DEBUGTrue也不会在开发配置里误写mem_limit: 16g导致笔记本卡死。所有环境差异都被收敛到各自的覆盖文件里主干配置永远干净。3. 核心部署步骤与实操细节全解析3.1 环境准备Ubuntu 上的 Docker Compose 安装避坑指南虽然热搜词里有“ubuntu安装docker compose”但实际安装远不止apt install docker-compose一行命令。Ubuntu 官方仓库的docker-compose包版本老旧常是 v1.x而 qKnow 的docker-compose.yml通常要求 v2.20因为用了profiles、x-*扩展等新语法。我推荐用 Docker 官方二进制安装法全程可控# 1. 卸载旧版如果存在 sudo apt remove docker-compose sudo rm /usr/local/bin/docker-compose # 2. 下载最新稳定版截至2024年v2.24.7 是主流 sudo curl -L https://github.com/docker/compose/releases/download/v2.24.7/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # 3. 添加执行权限 sudo chmod x /usr/local/bin/docker-compose # 4. 验证安装 docker-compose --version # 应输出 docker-compose version v2.24.7提示curl -L中的-L参数至关重要它允许 curl 跟随 GitHub 的重定向链接。如果漏掉你会下载到一个 HTML 重定向页而不是二进制文件后续执行docker-compose时会报Permission denied或Exec format error——这是新手最常见的“安装成功但无法运行”陷阱。安装完 Docker Compose别急着up先确认 Docker Engine 已启动且用户已加入docker组否则所有命令都会报permission denied# 检查 Docker 服务状态 sudo systemctl status docker # 应显示 active (running) # 将当前用户加入 docker 组避免每次都要 sudo sudo usermod -aG docker $USER # 重新登录或执行以下命令刷新组权限 newgrp docker # 验证不加 sudo 能否运行 docker ps # 应输出空列表无容器而非 permission error注意newgrp docker命令会启动一个新的 shell 会话如果你在 VS Code 终端里执行需要关掉终端再重开否则组权限不生效。很多用户卡在这一步反复sudo docker compose up却不知根本原因是权限没刷进去。3.2 数据库初始化MySQL 与 Neo4j 的首次握手qKnow 启动前MySQL 和 Neo4j 必须完成初始化否则后端服务会因连接失败而崩溃。这步不能跳过也不能依赖应用自动建库——因为 qKnow 的初始化脚本往往只建表不建库而 Neo4j 的 APOC 插件用于 CSV 导入导出必须手动启用。MySQL 初始化创建init.sql文件放在./mysql-init/目录下-- 创建 qKnow 专用数据库 CREATE DATABASE IF NOT EXISTS qknow_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建应用用户并授权比 root 更安全 CREATE USER qknow_user% IDENTIFIED BY qknow_pass; GRANT ALL PRIVILEGES ON qknow_db.* TO qknow_user%; FLUSH PRIVILEGES;修改docker-compose.yml中 MySQL 服务挂载初始化脚本mysql: # ... 其他配置 volumes: - ./mysql-data:/var/lib/mysql - ./mysql-init:/docker-entrypoint-initdb.d # 关键Docker MySQL 镜像会自动执行此目录下 .sql 文件Neo4j 初始化Neo4j 的难点不在建库而在插件。qKnow 的数据导入导出严重依赖 APOCAwesome Procedures on Cypher它不在默认安装包里必须手动下载并挂载创建./neo4j-plugins/目录并下载对应 Neo4j 版本的 APOC jar 包# 进入项目根目录 mkdir -p neo4j-plugins # 下载 APOC以 Neo4j 5.16 为例需匹配版本 wget -O neo4j-plugins/apoc-5.16.0-all.jar https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/5.16.0/apoc-5.16.0-all.jar确保docker-compose.yml中 Neo4j 服务正确挂载插件目录并启用相关配置neo4j: # ... 其他配置 volumes: - ./neo4j-data:/data - ./neo4j-plugins:/plugins # 必须挂载到 /plugins environment: # ... 其他环境变量 NEO4J_apoc_export_file_enabled: true NEO4J_apoc_import_file_enabled: true NEO4J_dbms_security_procedures_unrestricted: apoc.* # 允许 APOC 所有过程实操心得APOC 版本必须与 Neo4j 主版本严格一致。比如 Neo4j 5.16 只能用 apoc-5.16.x用 5.15 或 5.17 的 jar 包会导致 Neo4j 启动失败日志里满屏Failed to load plugin apoc。这个坑我踩过三次最后一次是直接去 APOC 的 GitHub Releases 页面按 Neo4j 版本号筛选下载链接再也不凭记忆手输。3.3 qKnow 后端构建与配置从源码到可运行服务qKnow 通常以源码形式提供你需要自己构建后端镜像。这步是部署中最容易出错的环节因为涉及 Python 依赖、模型路径、数据库连接参数三重校验。第一步获取源码并检查结构假设你从 GitHub 克隆了 qKnow 仓库git clone https://github.com/qknow-org/qknow.git cd qknow ls -l # 你应该看到backend/ frontend/ docker-compose.yml requirements.txt第二步修改后端配置文件进入backend/config.py重点修改三处# 1. MySQL 连接配置必须与 docker-compose.yml 中的 service name 一致 MYSQL_HOST mysql # 不是 localhost是 Compose 服务名 MYSQL_PORT 3306 MYSQL_USER qknow_user MYSQL_PASSWORD qknow_pass MYSQL_DB qknow_db # 2. Neo4j 连接配置Bolt 协议端口 7687 NEO4J_URI bolt://neo4j:7687 # 同样host 是服务名 NEO4J_USER neo4j NEO4J_PASSWORD password # 与 docker-compose.yml 中一致 # 3. DeepKE 模型路径关键 DEEPKE_MODEL_PATH /app/models/deepke_ner # 容器内路径 # 你必须在 docker-compose.yml 中把宿主机的模型文件夹挂载到这里第三步准备 DeepKE 模型qKnow 不自带预训练模型你需要单独下载。以中文 NER 模型为例# 创建模型目录 mkdir -p backend/models/deepke_ner # 下载官方模型示例链接以实际项目文档为准 wget -P backend/models/deepke_ner https://qknow-models.example.com/deepke_ner_chinese.zip unzip backend/models/deepke_ner/deepke_ner_chinese.zip -d backend/models/deepke_ner/第四步编写 Dockerfile如果项目没提供backend/Dockerfile示例FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制源码和模型注意模型必须 COPY 进镜像或通过 volume 挂载 COPY . . # 如果模型很大建议用 volume 挂载避免镜像臃肿 # COPY models/ /app/models/ EXPOSE 8000 CMD [uvicorn, main:app, --host, 0.0.0.0:8000, --port, 8000]第五步在 docker-compose.yml 中定义构建qknow-api: build: context: ./backend dockerfile: Dockerfile # ... 其他配置 volumes: - ./backend/models:/app/models # 模型通过 volume 挂载更灵活常见问题ModuleNotFoundError: No module named deepke。这是因为requirements.txt里写的deepke包名但 PyPI 上并没有这个包——它其实是 qKnow 项目自己 fork 的 DeepKE 仓库。正确做法是在requirements.txt里写githttps://github.com/qknow-org/deepke.gitv1.0.0#eggdeepke或者把 DeepKE 源码放backend/libs/deepke/然后在Dockerfile里COPY libs/deepke /usr/local/lib/python3.9/site-packages/deepke。我推荐后者因为网络不稳定时 git install 会失败。3.4 Gradio 前端启动与反向代理配置Gradio 服务通常由qknow-api直接提供但为了生产环境安全建议加一层 Nginx 反向代理实现 HTTPS、访问控制、静态资源缓存。Nginx 配置 (nginx.conf)events { worker_connections 1024; } http { upstream qknow_backend { server qknow-api:8000; # 指向 Compose 服务名 } server { listen 80; server_name localhost; # 强制 HTTPS如果已有证书 # return 301 https://$server_name$request_uri; location / { proxy_pass http://qknow_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # Gradio 的 WebSocket 支持用于实时流式响应 location /gradio/ { proxy_pass http://qknow_backend/gradio/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } } }在docker-compose.yml中添加 Nginx 服务nginx: image: nginx:alpine ports: - 80:80 - 443:443 # 如需 HTTPS volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./ssl:/etc/nginx/ssl # 如需 HTTPS 证书 depends_on: - qknow-api启动后访问http://localhost即可看到 Gradio 界面。此时所有请求都经由 Nginx 转发qknow-api容器无需暴露端口到宿主机安全性大幅提升。4. 常见问题排查与独家避坑技巧实录4.1 启动阶段高频报错与根因分析报错现象根本原因解决方案我的实测耗时ERROR: for qknow-api Cannot start service qknow-api: driver failed programming external connectivity on endpoint... Bind for 0.0.0.0:8000 failed: port is already allocated宿主机 8000 端口被占用如之前没down干净的容器或本地 Python 服务sudo lsof -i :8000查进程kill -9 PID杀掉或改docker-compose.yml中qknow-api的ports为8001:80002 分钟ERROR: for neo4j Cannot create container for service neo4j: invalid mount config for type bind: bind source path does not exist./neo4j-plugins目录不存在或路径写错如少了个.mkdir -p ./neo4j-plugins检查docker-compose.yml中volumes路径是否与ls输出一致1 分钟qknow-api_1 exited with code 1日志显示pymysql.err.OperationalError: (2003, Cant connect to MySQL server on mysql ([Errno -2] Name or service not known))qknow-api启动太快mysql容器 DNS 记录未生效或mysql容器根本没起来看docker compose ps在qknow-api的启动命令前加健康检查脚本或手动docker compose up mysql等其状态为healthy后再up qknow-api5 分钟首次→ 后续加脚本 0 分钟neo4j_1 exited with code 1日志末尾Plugin directory /plugins is not readable./neo4j-plugins目录权限不足Docker 容器内neo4j用户UID 7474无法读取sudo chown -R 7474:7474 ./neo4j-plugins或chmod -R 755 ./neo4j-plugins3 分钟注意chown -R 7474:7474是 Neo4j 官方镜像指定的用户 UID不是随意写的。你可以进容器查docker exec -it qknow-neo4j bash然后id -u neo4j确认。4.2 运行中典型故障与现场诊断法故障一Gradio 界面能打开但提问后无响应浏览器控制台报504 Gateway Timeout这是典型的 Nginx 代理超时。默认proxy_read_timeout是 60 秒而 DeepKE 处理一个长文档可能需要 90 秒。解决方案在nginx.conf的location /块里加proxy_read_timeout 300; # 改为 5 分钟 proxy_connect_timeout 300; proxy_send_timeout 300;故障二Neo4j Browser (http://localhost:7474) 能打开但执行MATCH (n) RETURN n LIMIT 10报错There is no procedure with the nameapoc.export.csvregistered for this database instance说明 APOC 插件没加载成功。检查三件事docker compose logs neo4j里是否有Failed to load plugin apoc./neo4j-plugins/目录下 jar 包是否真的存在且大小 0docker-compose.yml中NEO4J_apoc_*环境变量是否拼写正确注意下划线和大小写。我有一次发现 jar 包下载不完整ls -lh显示只有 1KB重新wget后问题解决。故障三MySQL 连接正常但 qKnow 后端日志报Table qknow_db.document doesnt exist这是 qKnow 的初始化脚本没运行。qKnow 通常提供init_db.py脚本需手动执行# 进入 qknow-api 容器 docker exec -it qknow-qknow-api-1 bash # 运行初始化路径以实际项目为准 cd /app python init_db.py这个脚本会创建document、entity、relation等核心表。很多项目 README 里只写了“运行后端”没强调“先初始化数据库”导致新手卡住。4.3 性能调优与稳定性加固实战内存爆满导致容器 OOM KilledqKnow 的瓶颈常在 Neo4j。默认配置下Neo4j 会吃光所有内存。在neo4j/conf/neo4j.conf需挂载中调整# 限制堆内存为 2GB根据你的机器调整 dbms.memory.heap.initial_size2G dbms.memory.heap.max_size2G # 限制 Page Cache 为 4GB dbms.memory.pagecache.size4G # 关闭不必要日志 dbms.logs.debug.levelOFFDeepKE 模型加载慢首次提问时后端要加载几百 MB 的 PyTorch 模型用户等待超 30 秒。解决方案在qknow-api启动时预加载模型。修改main.py# 在 app 实例创建后立即加载模型 app.on_event(startup) async def startup_event(): logger.info(Loading DeepKE model...) from deepke import load_model global deepke_model deepke_model load_model(/app/models/deepke_ner) # 路径与 config.py 一致 logger.info(DeepKE model loaded successfully.)防止数据意外丢失的黄金备份法每天凌晨 2 点自动备份 MySQL 和 Neo4j 数据# 创建 backup.sh #!/bin/bash DATE$(date %Y%m%d) docker exec qknow-mysql-1 mysqldump -uqknow_user -pqknow_pass qknow_db ./backup/mysql-$DATE.sql docker exec qknow-neo4j-1 bash -c neo4j-admin dump --to/tmp/neo4j-$DATE.dump docker cp qknow-neo4j-1:/tmp/neo4j-$DATE.dump ./backup/加到 crontab0 2 * * * /path/to/backup.sh最后分享一个小技巧部署完成后立刻在 Neo4j Browser 里执行:play movies跑通官方示例。这能 100% 验证 Neo4j APOC 浏览器三者联通。如果连这个都跑不通说明底层环境就有问题不用急着测 qKnow。这是我给自己定的“部署通过红线”——所有服务都 OK才能开始业务验证。