绿联NAS:搭建WeKnora — 让文档活起来

2026-07-26 20:32:28 0点赞 0收藏 0评论

一、项目介绍

WeKnora(维娜拉) 是一款开源的、基于大语言模型(LLM)的知识管理框架,专为企业级文档理解、语义检索与智能推理场景打造。

框架围绕三大核心能力构建:RAG 快速问答适合日常知识查询,ReAct Agent 智能推理自主编排知识检索、MCP 工具与网络搜索完成复杂多步任务,全新的 Wiki 模式则让 Agent 从原始文档中自治生成相互链接的 Markdown 知识库与可视化知识图谱。结合多源数据接入(飞书 / Notion / 语雀 / RSS,更多持续接入中)、网站嵌入 Widget 将智能体发布到外部站点、权限范围 API Key 与 Principal 模型面向程序化集成、每空间多实例存储后端灵活编排数据落地、二十余家主流模型厂商集成、Langfuse 全链路可观测性与运行时任务队列面板 + Worker 池治理、企业级多空间 RBAC(四级角色矩阵 + 资源归属 + 空间审计日志),以及完全可私有化部署的模块化架构,WeKnora 帮助团队把分散文档沉淀为可查询、可推理、可持续演进的专属知识资产。

框架支持从飞书、Notion 及语雀等外部平台自动同步知识(更多数据源持续接入中),覆盖 PDF、Word、图片、Excel 等十余种文档格式,并可通过企业微信、飞书、Slack、Telegram 等 IM 频道直接提供问答服务。模型层面兼容 OpenAIDeepSeek、Qwen(阿里云)、智谱、混元、Gemini、MiniMax、NVIDIA、Ollama 等主流厂商。全流程模块化设计,大模型、向量数据库、存储等组件均可灵活替换,支持本地与私有云部署,数据完全自主可控。WeKnora 还无缝集成了 Langfuse,为 Agent 运行、Token 使用及任务流水线提供了全面的可观测性追踪。

二、搭建教程(型号DH4300PLUS,同样适用X86机型)

1、打开文件管理器-找到docker共享文件夹-创建一个文件夹weknora;

2、下载项目到电脑文件夹-解压-编辑.env.example文件-全选内容复制粘贴一下内容;

# ================================================================= # WeKnora 环境变量配置(绿联云 UGOS Pro 专用) # 生成日期:2026-07-17 # 说明: # 1. 端口已调至 20000+ 避免与 NAS 系统服务冲突 # 2. 所有密码/密钥均为强随机值,请妥善保管 # 3. AES 密钥为 64 位十六进制(即 32 字节),符合 AES-256 要求 # 4. 若无需 Langfuse 可观测性,请注释掉 LANGFUSE_PUBLIC_KEY 和 SECRET_KEY # ================================================================= # ---------- 基础设置 ---------- # 镜像版本:latest(稳定版)或 main(最新开发版) WEKNORA_VERSION=latest # Gin 运行模式:release(生产)或 debug(开发) GIN_MODE=release # 日志级别:debug / info / warn / error / fatal LOG_LEVEL=debug # 时区(影响日志时间戳和任务调度) TZ=Asia/Shanghai # 系统默认语言(BCP-47 格式) WEKNORA_LANGUAGE=zh-CN # ---------- 端口映射(宿主机端口,可安全修改) ---------- # 前端 Web 端口(原 80 -> 28080,避免与 NAS 管理界面冲突) FRONTEND_PORT=28080 # 后端 API 服务端口(原 8080 -> 28081) APP_PORT=28081 # 说明:以下内部端口无需修改,保持默认即可 # APP_BACKEND_PORT=8080 # 容器内后端监听端口(不要改) # DB_PORT=5432 # PostgreSQL 容器内端口(不要改) # REDIS_ADDR=redis:6379 # Redis 内部地址(不要改) # ---------- 数据库配置(PostgreSQL/ParadeDB) ---------- # 数据库驱动(仅支持 postgres) DB_DRIVER=postgres # 数据库主机(内部服务名,不要改) DB_HOST=postgres # 数据库内部端口(容器内监听 5432,不要改) DB_PORT=5432 # 数据库用户名 DB_USER=postgres # 【必须修改】数据库密码(强随机,含特殊字符,已在 compose 中正确处理) DB_PASSWORD=Ug9#kL2$mNpQ5&xZvR7wY3@ # 数据库名称 DB_NAME=WeKnora # ---------- Redis 配置 ---------- # Redis 主机地址(内部服务名) REDIS_ADDR=redis:6379 # 【必须修改】Redis 密码(强随机) REDIS_PASSWORD=Fa8#sD4&hJkL9*PqW2@ # Redis 数据库索引(0-15,WeKnora 使用 0) REDIS_DB=0 # Redis key 前缀(用于命名空间隔离) REDIS_PREFIX=stream: # 流处理器类型(redis 或 memory) STREAM_MANAGER_TYPE=redis # ---------- 存储配置 ---------- # 向量检索驱动(postgres / qdrant / milvus / weaviate / elasticsearch 等) RETRIEVE_DRIVER=postgres # 文件存储类型(local / minio / cos / tos / s3 / obs) STORAGE_TYPE=local # 本地存储基础目录(容器内路径,由卷持久化) LOCAL_STORAGE_BASE_DIR=/data/files # 是否自动恢复脏数据 AUTO_RECOVER_DIRTY=true # ---------- AES 加密密钥(必须 32 字节) ---------- # 说明:此处使用 64 位十六进制表示(每个字符 4 位,共 64 字符 = 32 字节) # 若需重新生成,可执行:openssl rand -hex 32 # 租户 AES 密钥 TENANT_AES_KEY=8f7e2d1a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e # 系统 AES 密钥 SYSTEM_AES_KEY=1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 # ---------- 安全与认证 ---------- # JWT 签名密钥(64 位十六进制,安全强度高) JWT_SECRET=4f8e2d1a7b3c9e5f0d6a8b4c2e7f1a3d5b8c0e2f4a6d8b1c3e5f7a9c0d2e4f6 # 是否禁止新用户公开注册(生产环境建议 true) DISABLE_REGISTRATION=false # 注册后默认空间策略(create_personal / tenantless) # WEKNORA_AUTH_DEFAULT_TENANT_MODE=create_personal # 是否允许普通用户主动创建空间(默认 true) # WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED=true # ---------- 外部服务地址 ---------- # Ollama 服务地址(若在宿主机运行,保持 host.docker.internal) OLLAMA_BASE_URL=http://host.docker.internal:11434 # Docreader 服务地址(内部服务名) DOCREADER_ADDR=docreader:50051 DOCREADER_TRANSPORT=grpc # ---------- 并发与性能 ---------- # 嵌入/模型并发数(遇 429 可调小) CONCURRENCY_POOL_SIZE=5 # 异步任务并发(可根据机器性能调整) # WEKNORA_ASYNQ_CORE_CONCURRENCY=8 # WEKNORA_ASYNQ_POSTPROCESS_CONCURRENCY=2 # WEKNORA_ASYNQ_ENRICHMENT_CONCURRENCY=12 # WEKNORA_ASYNQ_MAINTENANCE_CONCURRENCY=4 # WEKNORA_ASYNQ_SHARED_CONCURRENCY=6 # WEKNORA_WIKI_ASYNQ_CONCURRENCY=8 # WEKNORA_MODEL_MAX_CONCURRENCY=32 # ---------- 知识图谱(Neo4j) ---------- # 是否启用图 RAG(需额外资源,默认关闭) ENABLE_GRAPH_RAG=false # Neo4j 连接参数(若启用请取消注释并配置) # NEO4J_ENABLE=false # NEO4J_URI=bolt://neo4j:7687 # NEO4J_USERNAME=neo4j # NEO4J_PASSWORD=password # ---------- Agent 沙箱 ---------- # 沙箱模式:docker / local / disabled WEKNORA_SANDBOX_MODE=docker # 脚本执行超时(秒) WEKNORA_SANDBOX_TIMEOUT=60 # Agent LLM 调用超时(秒),复杂任务可调大 # WEKNORA_AGENT_LLM_TIMEOUT=300 # MCP 工具人工审核等待超时(秒) # WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT=600 # ---------- 租户与 RBAC ---------- # 启用空间级 RBAC(默认 true) # WEKNORA_TENANT_ENABLE_RBAC=true # 单个用户最大可创建空间数(0 使用默认,-1 关闭限制) # WEKNORA_TENANT_MAX_OWNED_PER_USER= # 创建空间时是否自动生成全量 API Key(默认 false) # WEKNORA_TENANT_AUTO_CREATE_API_KEY=false # 系统管理员引导邮箱(首次启动自动提权) # WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL= # ---------- 聊天附件与 OCR ---------- # 附件保留时间(小时) # WEKNORA_CHAT_ATTACHMENT_TTL_HOURS=24 # 附件解析等待超时(秒) # WEKNORA_CHAT_ATTACHMENT_WAIT_TIMEOUT_SEC=60 # OCR 并发数 # WEKNORA_CHAT_ATTACHMENT_OCR_CONCURRENCY=8 # OCR 最大页数 # WEKNORA_CHAT_ATTACHMENT_OCR_MAX_PAGES=8 # ---------- SSRF 白名单 ---------- # 默认已包含内置服务(searxng, qdrant, milvus, weaviate, doris-fe) # 若需添加自定义地址,请追加到 SSRF_WHITELIST_EXTRA SSRF_WHITELIST_EXTRA=searxng,qdrant,milvus,weaviate,doris-fe # ---------- Langfuse 可观测性(可选) ---------- # 注意:若不使用,请将下面两行注释掉,否则应用启动会尝试连接 Langfuse # LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx # LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx # 若自建 Langfuse,取消注释并设置 HOST # LANGFUSE_HOST=http://langfuse-web:3000 # 其他 Langfuse 参数(可选) # LANGFUSE_RELEASE=v0.4.2 # LANGFUSE_ENVIRONMENT=production # LANGFUSE_FLUSH_AT=15 # LANGFUSE_SAMPLE_RATE=1.0 # ---------- APK 镜像源(加速 Alpine 构建) ---------- APK_MIRROR_ARG=mirrors.tencent.com # ---------- 以下为高级存储配置(按需启用) ---------- # 若需使用 MinIO,取消注释并配置,同时启用 profile minio # MINIO_ENDPOINT=minio:9000 # MINIO_ACCESS_KEY_ID=minioadmin # MINIO_SECRET_ACCESS_KEY=minioadmin # MINIO_BUCKET_NAME=weknora # 腾讯云 COS # COS_SECRET_ID=xxx # COS_SECRET_KEY=xxx # COS_REGION=ap-guangzhou # COS_BUCKET_NAME=xxx # COS_APP_ID=xxx # COS_PATH_PREFIX=weknora/ # COS_ENABLE_OLD_DOMAIN=true # 华为 OBS # OBS_ENDPOINT=obs.cn-north-4.myhuaweicloud.com # OBS_REGION=cn-north-4 # OBS_ACCESS_KEY=xxx # OBS_SECRET_KEY=xxx # OBS_BUCKET_NAME=xxx # OBS_PATH_PREFIX=weknora/ # AWS S3 # S3_ENDPOINT=https://s3.amazonaws.com # S3_REGION=us-east-1 # S3_ACCESS_KEY=xxx # S3_SECRET_KEY=xxx # S3_BUCKET_NAME=xxx # S3_PATH_PREFIX=weknora/ # ---------- 其他向量数据库(按需启用) ---------- # Qdrant # QDRANT_HOST=qdrant # QDRANT_PORT=6334 # QDRANT_COLLECTION=weknora_embeddings # Milvus # MILVUS_ADDRESS=milvus:19530 # MILVUS_COLLECTION=weknora_embeddings # MILVUS_METRIC_TYPE=IP # Weaviate # WEAVIATE_HOST=weaviate:8080 # WEAVIATE_GRPC_ADDRESS=weaviate:50051 # WEAVIATE_SCHEME=http # WEAVIATE_AUTH_ENABLED=false # Doris # DORIS_ADDR=doris-fe:9030 # DORIS_HTTP_PORT=8030 # DORIS_DATABASE=weknora # DORIS_USERNAME=root # DORIS_PASSWORD= # DORIS_TABLE_PREFIX=weknora_embeddings # ---------- 文件上传大小限制 ---------- # MAX_FILE_SIZE_MB=50 # ---------- 外部访问 URL(用于 IM 渠道) ---------- # APP_EXTERNAL_URL=http://你的公网IP:28080

3、保存后把文件名修改为.env,然后打开文件管理器,找到左小角设置-隐藏指定文件-取消以点开头-保存;

绿联NAS:搭建WeKnora — 让文档活起来绿联NAS:搭建WeKnora — 让文档活起来

4、把解压的所有文件传到weknora文件夹,文件较多一定要等待所有文件传输完成;

绿联NAS:搭建WeKnora — 让文档活起来

5、打开docker-选择项目-创建-输入项目名weknora-自动带出存放路径;

绿联NAS:搭建WeKnora — 让文档活起来

6、把下方docker compose粘贴进去;

# ============================================================================= # WeKnora Docker Compose 配置(绿联云 UGOS Pro 专用) # 版本:最新稳定版 # 说明:所有可变值均通过 .env 文件注入,请勿硬编码敏感信息 # 使用前请确保 ./config/config.yaml 存在,且 Redis 密码不含易被 shell 截断的字符 # ============================================================================= # ---------- 网络定义 ---------- # 所有服务共享此内部网络,通过服务名(如 app、postgres)互相访问 networks: WeKnora-network: driver: bridge # ---------- 卷定义 ---------- # 命名卷由 Docker 管理,数据保存在 Docker 数据目录(如 /var/lib/docker/volumes/) # 建议定期备份 postgres-data 和 data-files(核心业务数据) volumes: postgres-data: # PostgreSQL 数据库文件(最重要!) data-files: # 用户上传的文档、图片等(核心数据) docreader-tmp: # 文档解析临时文件(可随时清理) minio_data: # MinIO 对象存储数据(若启用 minio profile) neo4j-data: # Neo4j 图数据库数据(若启用 neo4j profile) qdrant_data: # Qdrant 向量库数据(若启用 qdrant profile) milvus_data: # Milvus 向量库数据(若启用 milvus profile) weaviate_data: # Weaviate 向量库数据(若启用 weaviate profile) doris_fe_meta: # Doris FE 元数据(若启用 doris profile) doris_fe_log: # Doris FE 日志 doris_be_storage: # Doris BE 存储 doris_be_log: # Doris BE 日志 langfuse_clickhouse_data: # Langfuse ClickHouse 数据(若启用 langfuse profile) langfuse_clickhouse_logs: # Langfuse ClickHouse 日志 langfuse_minio_data: # Langfuse 专用 MinIO 数据 searxng_config: # SearXNG 配置文件卷(若启用 searxng profile) # ---------- 服务定义 ---------- services: # ============================================================ # 1. 前端服务 (frontend) # 基于 Nginx 提供 Web 界面,并反向代理 API 请求到后端 # ============================================================ frontend: image: wechatopenai/weknora-ui:${WEKNORA_VERSION:-latest} # 若需本地构建,需先执行 ./scripts/build_frontend_dist.sh build: context: ./frontend container_name: WeKnora-frontend # 宿主机端口由 FRONTEND_PORT 控制(默认 80,现已改为 28080) ports: - "${FRONTEND_PORT:-80}:80" environment: - MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50} - APP_HOST=${APP_HOST:-app} # 后端服务名(容器内 DNS) - APP_PORT=${APP_BACKEND_PORT:-8080} # 后端容器监听端口 - APP_SCHEME=${APP_SCHEME:-http} # 协议(http/https) depends_on: app: condition: service_healthy # 等待 app 健康后再启动 networks: - WeKnora-network restart: unless-stopped # ============================================================ # 2. 后端应用服务 (app) # 核心业务:知识库管理、对话、检索、Agent、文件处理等 # ============================================================ app: image: wechatopenai/weknora-app:${WEKNORA_VERSION:-latest} build: context: . dockerfile: docker/Dockerfile.app args: - APK_MIRROR_ARG=${APK_MIRROR_ARG:-} # Alpine 镜像源加速(如 mirrors.tencent.com) container_name: WeKnora-app # 宿主机端口由 APP_PORT 控制(默认 8080,现已改为 28081) ports: - "${APP_PORT:-8080}:8080" volumes: # --- 命名卷(Docker 管理,推荐用于有状态数据) --- - data-files:/data/files # 上传文件持久化(务必定期备份) - docreader-tmp:/tmp/docreader:ro # 只读挂载 docreader 临时目录 # --- 绑定挂载(相对路径,便于直接编辑) --- - ./config/config.yaml:/app/config/config.yaml # 主配置文件(必须存在!) - ./skills/preloaded:/app/skills/preloaded # 自定义技能目录(可选) # 若需内置模型声明,可复制 config/builtin_models.yaml.example 并取消注释下行 # - ./config/builtin_models.yaml:/app/config/builtin_models.yaml:ro healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s # 从 .env 加载全部环境变量,供配置文件(如 builtin_models.yaml)使用 ${VAR} 引用 env_file: - .env environment: # 以下所有变量均从 .env 读取,若未设置则使用默认值 - LOG_LEVEL=${LOG_LEVEL:-} # --- 对象存储(腾讯云 COS) --- - COS_SECRET_ID=${COS_SECRET_ID:-} - COS_SECRET_KEY=${COS_SECRET_KEY:-} - COS_REGION=${COS_REGION:-} - COS_BUCKET_NAME=${COS_BUCKET_NAME:-} - COS_APP_ID=${COS_APP_ID:-} - COS_PATH_PREFIX=${COS_PATH_PREFIX:-} - COS_ENABLE_OLD_DOMAIN=${COS_ENABLE_OLD_DOMAIN:-} # --- 运行模式与安全 --- - GIN_MODE=${GIN_MODE:-release} - DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-false} - WEKNORA_AUTH_DEFAULT_TENANT_MODE=${WEKNORA_AUTH_DEFAULT_TENANT_MODE:-} - WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED=${WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED:-} # --- 数据库(PostgreSQL) --- - DB_DRIVER=${DB_DRIVER:-postgres} - DB_HOST=${DB_HOST:-postgres} # 内部服务名,不要改 - DB_PORT=${DB_PORT:-5432} # 容器内部端口,不要改! - DB_USER=${DB_USER:-} - DB_PASSWORD=${DB_PASSWORD:-} - DB_NAME=${DB_NAME:-} - TZ=${TZ:-Asia/Shanghai} - WEKNORA_LANGUAGE=${WEKNORA_LANGUAGE:-zh-CN} # --- Langfuse 可观测性(可选) --- # 同时设置 PUBLIC_KEY 和 SECRET_KEY 即自动启用 - LANGFUSE_ENABLED=${LANGFUSE_ENABLED:-} - LANGFUSE_HOST=${LANGFUSE_HOST:-https://cloud.langfuse.com} - LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-} - LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-} - LANGFUSE_RELEASE=${LANGFUSE_RELEASE:-} - LANGFUSE_ENVIRONMENT=${LANGFUSE_ENVIRONMENT:-} - LANGFUSE_FLUSH_AT=${LANGFUSE_FLUSH_AT:-} - LANGFUSE_FLUSH_INTERVAL=${LANGFUSE_FLUSH_INTERVAL:-} - LANGFUSE_QUEUE_SIZE=${LANGFUSE_QUEUE_SIZE:-} - LANGFUSE_REQUEST_TIMEOUT=${LANGFUSE_REQUEST_TIMEOUT:-} - LANGFUSE_SAMPLE_RATE=${LANGFUSE_SAMPLE_RATE:-} - LANGFUSE_DEBUG=${LANGFUSE_DEBUG:-} # --- 向量检索驱动 --- - RETRIEVE_DRIVER=${RETRIEVE_DRIVER:-} # Elasticsearch - ELASTICSEARCH_ADDR=${ELASTICSEARCH_ADDR:-} - ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME:-} - ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD:-} - ELASTICSEARCH_INDEX=${ELASTICSEARCH_INDEX:-} # Qdrant - QDRANT_HOST=${QDRANT_HOST:-qdrant} - QDRANT_PORT=${QDRANT_PORT:-6334} - QDRANT_COLLECTION=${QDRANT_COLLECTION:-weknora_embeddings} - QDRANT_API_KEY=${QDRANT_API_KEY:-} - QDRANT_USE_TLS=${QDRANT_USE_TLS:-false} # Milvus - MILVUS_ADDRESS=${MILVUS_ADDRESS:-milvus:19530} - MILVUS_COLLECTION=${MILVUS_COLLECTION:-weknora_embeddings} - MILVUS_METRIC_TYPE=${MILVUS_METRIC_TYPE:-IP} # --- 文档解析服务 --- - DOCREADER_ADDR=${DOCREADER_ADDR:-docreader:50051} - DOCREADER_TRANSPORT=${DOCREADER_TRANSPORT:-grpc} - GRPC_TLS_ENABLED=${GRPC_TLS_ENABLED:-false} - GRPC_TLS_CERT=${GRPC_TLS_CERT:-} - GRPC_TLS_KEY=${GRPC_TLS_KEY:-} - GRPC_TLS_CA=${GRPC_TLS_CA:-} - GRPC_TLS_SERVER_NAME=${GRPC_TLS_SERVER_NAME:-} - GRPC_AUTH_TOKEN=${GRPC_AUTH_TOKEN:-} # Weaviate - WEAVIATE_HOST=${WEAVIATE_HOST:-weaviate:8080} - WEAVIATE_GRPC_ADDRESS=${WEAVIATE_GRPC_ADDRESS:-weaviate:50051} - WEAVIATE_SCHEME=${WEAVIATE_SCHEME:-http} - WEAVIATE_AUTH_ENABLED=${WEAVIATE_AUTH_ENABLED:-false} - WEAVIATE_API_KEY=${WEAVIATE_API_KEY:-} # Apache Doris - DORIS_ADDR=${DORIS_ADDR:-doris-fe:9030} - DORIS_HTTP_PORT=${DORIS_HTTP_PORT:-8030} - DORIS_DATABASE=${DORIS_DATABASE:-weknora} - DORIS_USERNAME=${DORIS_USERNAME:-root} - DORIS_PASSWORD=${DORIS_PASSWORD:-} - DORIS_TABLE_PREFIX=${DORIS_TABLE_PREFIX:-weknora_embeddings} - DORIS_COMPAT_MODE=${DORIS_COMPAT_MODE:-auto} # --- 文件存储 --- - STORAGE_TYPE=${STORAGE_TYPE:-} - LOCAL_STORAGE_BASE_DIR=${LOCAL_STORAGE_BASE_DIR:-} - AUTO_RECOVER_DIRTY=${AUTO_RECOVER_DIRTY:-true} # MinIO - MINIO_ENDPOINT=${MINIO_ENDPOINT:-minio:9000} - MINIO_ACCESS_KEY_ID=${MINIO_ACCESS_KEY_ID:-minioadmin} - MINIO_SECRET_ACCESS_KEY=${MINIO_SECRET_ACCESS_KEY:-minioadmin} - MINIO_BUCKET_NAME=${MINIO_BUCKET_NAME:-} # 华为 OBS - OBS_ENDPOINT=${OBS_ENDPOINT:-} - OBS_REGION=${OBS_REGION:-} - OBS_ACCESS_KEY=${OBS_ACCESS_KEY:-} - OBS_SECRET_KEY=${OBS_SECRET_KEY:-} - OBS_BUCKET_NAME=${OBS_BUCKET_NAME:-} - OBS_PATH_PREFIX=${OBS_PATH_PREFIX:-} - OBS_PROXY_DOMAIN=${OBS_PROXY_DOMAIN:-} # --- Ollama --- - OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://host.docker.internal:11434} # --- 流管理 --- - STREAM_MANAGER_TYPE=${STREAM_MANAGER_TYPE:-} # --- Redis --- - REDIS_ADDR=${REDIS_ADDR:-redis:6379} - REDIS_USERNAME=${REDIS_USERNAME:-} - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=${REDIS_DB:-} - REDIS_PREFIX=${REDIS_PREFIX:-} # --- 图 RAG(Neo4j) --- - ENABLE_GRAPH_RAG=${ENABLE_GRAPH_RAG:-} - NEO4J_ENABLE=${NEO4J_ENABLE:-} - NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687} - NEO4J_USERNAME=${NEO4J_USERNAME:-neo4j} - NEO4J_PASSWORD=${NEO4J_PASSWORD:-password} # --- 加密密钥 --- - TENANT_AES_KEY=${TENANT_AES_KEY:-} - SYSTEM_AES_KEY=${SYSTEM_AES_KEY:-} # --- SSRF 白名单 --- - SSRF_WHITELIST=${SSRF_WHITELIST:-} - IMAGE_HOST_KEEP_URL=${IMAGE_HOST_KEEP_URL:-} - SSRF_WHITELIST_EXTRA=${SSRF_WHITELIST_EXTRA:-searxng,qdrant,milvus,weaviate,doris-fe} # --- 并发与性能 --- - CONCURRENCY_POOL_SIZE=${CONCURRENCY_POOL_SIZE:-5} - JWT_SECRET=${JWT_SECRET:-} - CRYPTO_MASTER_KEY=${CRYPTO_MASTER_KEY:-} - CRYPTO_SALT=${CRYPTO_SALT:-} - MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-50} # --- 聊天附件 --- - WEKNORA_CHAT_ATTACHMENT_TTL_HOURS=${WEKNORA_CHAT_ATTACHMENT_TTL_HOURS:-24} - WEKNORA_CHAT_ATTACHMENT_WAIT_TIMEOUT_SEC=${WEKNORA_CHAT_ATTACHMENT_WAIT_TIMEOUT_SEC:-60} - WEKNORA_CHAT_ATTACHMENT_OCR_CONCURRENCY=${WEKNORA_CHAT_ATTACHMENT_OCR_CONCURRENCY:-8} - WEKNORA_CHAT_ATTACHMENT_OCR_MAX_PAGES=${WEKNORA_CHAT_ATTACHMENT_OCR_MAX_PAGES:-8} # --- Agent 沙箱 --- - WEKNORA_SANDBOX_MODE=${WEKNORA_SANDBOX_MODE:-docker} - WEKNORA_SANDBOX_TIMEOUT=${WEKNORA_SANDBOX_TIMEOUT:-60} - WEKNORA_SANDBOX_DOCKER_IMAGE=${WEKNORA_SANDBOX_DOCKER_IMAGE:-wechatopenai/weknora-sandbox:${WEKNORA_VERSION:-latest}} - WEKNORA_AGENT_LLM_TIMEOUT=${WEKNORA_AGENT_LLM_TIMEOUT:-} - WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT=${WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT:-} # --- 租户 RBAC --- - WEKNORA_TENANT_ENABLE_RBAC=${WEKNORA_TENANT_ENABLE_RBAC:-} - WEKNORA_TENANT_MAX_OWNED_PER_USER=${WEKNORA_TENANT_MAX_OWNED_PER_USER:-} - WEKNORA_TENANT_AUTO_CREATE_API_KEY=${WEKNORA_TENANT_AUTO_CREATE_API_KEY:-} # --- 异步任务并发控制 --- - WEKNORA_ASYNQ_CORE_CONCURRENCY=${WEKNORA_ASYNQ_CORE_CONCURRENCY:-8} - WEKNORA_ASYNQ_POSTPROCESS_CONCURRENCY=${WEKNORA_ASYNQ_POSTPROCESS_CONCURRENCY:-2} - WEKNORA_ASYNQ_ENRICHMENT_CONCURRENCY=${WEKNORA_ASYNQ_ENRICHMENT_CONCURRENCY:-12} - WEKNORA_ASYNQ_MAINTENANCE_CONCURRENCY=${WEKNORA_ASYNQ_MAINTENANCE_CONCURRENCY:-4} - WEKNORA_ASYNQ_SHARED_CONCURRENCY=${WEKNORA_ASYNQ_SHARED_CONCURRENCY:-6} - WEKNORA_WIKI_ASYNQ_CONCURRENCY=${WEKNORA_WIKI_ASYNQ_CONCURRENCY:-8} - WEKNORA_MODEL_MAX_CONCURRENCY=${WEKNORA_MODEL_MAX_CONCURRENCY:-32} - APK_MIRROR_ARG=${APK_MIRROR_ARG:-} - WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL=${WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL:-} depends_on: redis: condition: service_started postgres: condition: service_healthy docreader: condition: service_healthy networks: - WeKnora-network restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" # 使容器能访问宿主机的 Ollama 等服务 # ============================================================ # 3. 沙箱服务 (sandbox) # 仅用于构建/拉取沙箱镜像,实际 Skills 执行由 app 通过 Docker API 按需启动 # ============================================================ sandbox: image: wechatopenai/weknora-sandbox:${WEKNORA_VERSION:-latest} container_name: WeKnora-sandbox build: context: . dockerfile: docker/Dockerfile.sandbox profiles: - full command: ["true"] restart: "no" # ============================================================ # 4. 文档解析服务 (docreader) # 提供 gRPC 接口,用于 PDF、Office、图片的解析、OCR 和版式识别 # ============================================================ docreader: image: wechatopenai/weknora-docreader:${WEKNORA_VERSION:-latest} build: context: . dockerfile: docker/Dockerfile.docreader args: - APT_MIRROR=${APT_MIRROR:-} container_name: WeKnora-docreader expose: - "50051" # 仅内部网络可访问,不映射到宿主机 volumes: - docreader-tmp:/tmp/docreader environment: - TZ=${TZ:-Asia/Shanghai} - DOCREADER_IMAGE_OUTPUT_DIR=/tmp/docreader - DOCREADER_PDF_FORCE_SCANNED=${DOCREADER_PDF_FORCE_SCANNED:-false} - MAX_FILE_SIZE_MB=${MAX_FILE_SIZE_MB:-} - DOCREADER_ODL_MAX_WORKERS=${DOCREADER_ODL_MAX_WORKERS:-1} - DOCREADER_ODL_HYBRID=${DOCREADER_ODL_HYBRID:-off} - DOCREADER_ODL_HYBRID_URL=${DOCREADER_ODL_HYBRID_URL:-http://odl-hybrid:5002} - DOCREADER_ODL_HYBRID_MODE=${DOCREADER_ODL_HYBRID_MODE:-auto} - DOCREADER_ODL_HYBRID_FALLBACK=${DOCREADER_ODL_HYBRID_FALLBACK:-false} - DOCREADER_ODL_MARKDOWN_WITH_HTML=${DOCREADER_ODL_MARKDOWN_WITH_HTML:-false} - DOCREADER_MARKITDOWN_MAX_WORKERS=${DOCREADER_MARKITDOWN_MAX_WORKERS:-1} - DOCREADER_PDF_RENDER_MAX_WORKERS=${DOCREADER_PDF_RENDER_MAX_WORKERS:-1} - DOCREADER_PDF_RENDER_DPI=${DOCREADER_PDF_RENDER_DPI:-200} - DOCREADER_PDF_JPEG_QUALITY=${DOCREADER_PDF_JPEG_QUALITY:-90} - GRPC_TLS_ENABLED=${GRPC_TLS_ENABLED:-false} - GRPC_TLS_CERT=${GRPC_TLS_CERT:-} - GRPC_TLS_KEY=${GRPC_TLS_KEY:-} - GRPC_TLS_CA=${GRPC_TLS_CA:-} - GRPC_AUTH_TOKEN=${GRPC_AUTH_TOKEN:-} healthcheck: test: ["CMD", "grpc_health_probe", "-addr=localhost:50051"] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - WeKnora-network restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" # ============================================================ # 5. OpenDataLoader Hybrid(可选增强解析器) # 启用 profile odl-hybrid 并本地构建(镜像 tag: local) # ============================================================ odl-hybrid: build: context: . dockerfile: docker/Dockerfile.odl-hybrid image: weknora-odl-hybrid:local container_name: WeKnora-odl-hybrid profiles: - odl-hybrid expose: - "5002" environment: - ODL_HYBRID_EXTRA_ARGS=${ODL_HYBRID_EXTRA_ARGS:---no-ocr} networks: - WeKnora-network restart: unless-stopped # ============================================================ # 6. PostgreSQL + ParadeDB(主数据库) # 存储业务数据、向量嵌入、全文检索 # ============================================================ postgres: image: paradedb/paradedb:v0.22.2-pg17 container_name: WeKnora-postgres environment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} volumes: - postgres-data:/var/lib/postgresql/data networks: - WeKnora-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"] interval: 10s timeout: 10s retries: 3 start_period: 30s restart: unless-stopped stop_grace_period: 1m # 若需从宿主机外部连接数据库(如 pgAdmin),可取消注释下行 # ports: # - "25432:5432" # ============================================================ # 7. Redis(缓存 / 消息队列) # 注意:command 使用数组格式,避免密码中的特殊字符被 shell 截断 # ============================================================ redis: image: redis:7.0-alpine container_name: WeKnora-redis command: - redis-server - --appendonly - yes - --requirepass - ${REDIS_PASSWORD} restart: always networks: - WeKnora-network # ============================================================ # 8. SearXNG 初始化器(一次性) # 将模板 settings.yml 复制到配置卷 # ============================================================ searxng-init: image: busybox:1.36 container_name: WeKnora-searxng-init command: ["sh", "-c", "cp /template/settings.yml /etc/searxng/settings.yml && chmod 0644 /etc/searxng/settings.yml"] volumes: - ./docker/searxng/settings.yml:/template/settings.yml:ro - searxng_config:/etc/searxng restart: "no" networks: - WeKnora-network profiles: - searxng - full # ============================================================ # 9. SearXNG 搜索引擎(可选) # 提供元搜索能力,默认仅绑定 127.0.0.1 确保安全 # ============================================================ searxng: image: searxng/searxng:latest container_name: WeKnora-searxng ports: - "${SEARXNG_BIND:-127.0.0.1}:${SEARXNG_PORT:-8888}:8080" volumes: - searxng_config:/etc/searxng environment: - SEARXNG_BASE_URL=http://localhost:${SEARXNG_PORT:-8888}/ - INSTANCE_NAME=weknora-searxng - SEARXNG_SECRET=${SEARXNG_SECRET:-weknora-default-searxng-secret-rotate-before-exposing-publicly} cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID restart: unless-stopped depends_on: searxng-init: condition: service_completed_successfully networks: - WeKnora-network profiles: - searxng - full # ============================================================ # 10. MinIO(可选对象存储) # 启用 profile minio 后使用,替代 local 存储 # ============================================================ minio: image: minio/minio:RELEASE.2025-09-07T16-13-09Z container_name: WeKnora-minio ports: - "${MINIO_PORT:-9000}:9000" - "${MINIO_CONSOLE_PORT:-9001}:9001" environment: - MINIO_ROOT_USER=${MINIO_ACCESS_KEY_ID:-minioadmin} - MINIO_ROOT_PASSWORD=${MINIO_SECRET_ACCESS_KEY:-minioadmin} command: server --console-address ":9001" /data volumes: - minio_data:/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 networks: - WeKnora-network profiles: - minio - full # ============================================================ # 11. Neo4j(可选图数据库) # 用于知识图谱构建,启用 profile neo4j # ============================================================ neo4j: image: neo4j:2025.10.1 container_name: WeKnora-neo4j volumes: - neo4j-data:/data environment: - NEO4J_AUTH=${NEO4J_USERNAME:-neo4j}/${NEO4J_PASSWORD:-password} - NEO4J_apoc_export_file_enabled=true - NEO4J_apoc_import_file_enabled=true - NEO4J_apoc_import_file_use__neo4j__config=true - NEO4JLABS_PLUGINS=["apoc"] ports: - "7474:7474" # HTTP 控制台 - "7687:7687" # Bolt 协议 restart: always networks: - WeKnora-network profiles: - neo4j - full # ============================================================ # 12. Qdrant(可选向量数据库) # 高性能 ANN 检索,启用 profile qdrant # ============================================================ qdrant: image: qdrant/qdrant:v1.16.2 container_name: WeKnora-qdrant ports: - "${QDRANT_REST_PORT:-6333}:6333" - "${QDRANT_PORT:-6334}:6334" volumes: - qdrant_data:/qdrant/storage networks: - WeKnora-network restart: unless-stopped profiles: - qdrant - full # ============================================================ # 13. Milvus(可选向量数据库) # 功能完整,启用 profile milvus # ============================================================ milvus: image: milvusdb/milvus:v2.6.11 container_name: WeKnora-milvus security_opt: - seccomp:unconfined command: ["milvus", "run", "standalone"] environment: - ETCD_USE_EMBED=true - ETCD_DATA_DIR=/var/lib/milvus/etcd - COMMON_STORAGETYPE=local - DEPLOY_MODE=STANDALONE healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"] interval: 30s start_period: 90s timeout: 20s retries: 3 ports: - "19530:19530" - "9091:9091" volumes: - milvus_data:/var/lib/milvus networks: - WeKnora-network restart: unless-stopped profiles: - milvus # ============================================================ # 14. Weaviate(可选向量数据库) # 轻量级,支持 GraphQL,启用 profile weaviate # ============================================================ weaviate: image: semitechnologies/weaviate:1.28.4 container_name: WeKnora-weaviate environment: - PERSISTENCE_DATA_PATH=/var/lib/weaviate - CLUSTER_HOSTNAME=node1 - DEFAULT_VECTORIZER_MODULE=none - ENABLE_MODULES=none - AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true - CLUSTER_GOSSIP_BIND_PORT=7000 - CLUSTER_DATA_BIND_PORT=7001 - RAFT_BOOTSTRAP_EXPECT=1 ports: - "9035:8080" - "50052:50051" volumes: - weaviate_data:/var/lib/weaviate networks: - WeKnora-network restart: unless-stopped profiles: - weaviate # ============================================================ # 15. Apache Doris(可选 OLAP 向量库) # FE + BE 单节点,启用 profile doris # ============================================================ doris-fe: image: apache/doris:fe-4.1.0 container_name: WeKnora-doris-fe hostname: doris-fe environment: - FE_SERVERS=fe1:doris-fe:9010 - FE_ID=1 ports: - "${DORIS_FE_HTTP_PORT:-8030}:8030" - "${DORIS_FE_MYSQL_PORT:-9030}:9030" volumes: - doris_fe_meta:/opt/apache-doris/fe/doris-meta - doris_fe_log:/opt/apache-doris/fe/log networks: - WeKnora-network restart: unless-stopped profiles: - doris doris-be: image: apache/doris:be-4.1.0 container_name: WeKnora-doris-be hostname: doris-be environment: - FE_SERVERS=fe1:doris-fe:9010 - BE_ADDR=doris-be:9050 depends_on: - doris-fe ports: - "${DORIS_BE_HTTP_PORT:-8040}:8040" volumes: - doris_be_storage:/opt/apache-doris/be/storage - doris_be_log:/opt/apache-doris/be/log networks: - WeKnora-network restart: unless-stopped profiles: - doris # ============================================================ # 16. Dex(可选 OIDC 认证服务) # 需启用 profile dex 并准备 ./misc/dex-config.yaml # ============================================================ dex: image: dexidp/dex:latest container_name: dex ports: - "5556:5556" volumes: - ./misc/dex-config.yaml:/etc/dex/config.yaml command: ["dex", "serve", "/etc/dex/config.yaml"] profiles: - dex - full # ============================================================ # 17. Langfuse 自建可观测栈(可选) # 启用 profile langfuse 后启动全套组件(Web + Worker + ClickHouse + MinIO) # ============================================================ langfuse-db-init: image: paradedb/paradedb:v0.22.2-pg17 container_name: WeKnora-langfuse-db-init depends_on: postgres: condition: service_healthy environment: PGPASSWORD: ${DB_PASSWORD} entrypoint: ["sh", "-c"] command: - | set -e echo "[langfuse-db-init] ensuring database '${LANGFUSE_DB_NAME:-langfuse}' exists..." psql -h postgres -U ${DB_USER} -d postgres -v ON_ERROR_STOP=0 -c "ALTER DATABASE template1 REFRESH COLLATION VERSION;" >/dev/null 2>&1 || true psql -h postgres -U ${DB_USER} -d postgres -v ON_ERROR_STOP=0 -c "ALTER DATABASE postgres REFRESH COLLATION VERSION;" >/dev/null 2>&1 || true if psql -h postgres -U ${DB_USER} -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname='${LANGFUSE_DB_NAME:-langfuse}'" | grep -q 1; then echo "[langfuse-db-init] database '${LANGFUSE_DB_NAME:-langfuse}' already exists, skipping." else psql -h postgres -U ${DB_USER} -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE "${LANGFUSE_DB_NAME:-langfuse}" TEMPLATE template0;" echo "[langfuse-db-init] database '${LANGFUSE_DB_NAME:-langfuse}' created." fi echo "[langfuse-db-init] done." networks: - WeKnora-network restart: "no" profiles: - langfuse - full langfuse-clickhouse: image: clickhouse/clickhouse-server:24.8 container_name: WeKnora-langfuse-clickhouse restart: unless-stopped user: "101:101" environment: CLICKHOUSE_DB: default CLICKHOUSE_USER: ${LANGFUSE_CLICKHOUSE_USER:-clickhouse} CLICKHOUSE_PASSWORD: ${LANGFUSE_CLICKHOUSE_PASSWORD:-clickhouse} volumes: - langfuse_clickhouse_data:/var/lib/clickhouse - langfuse_clickhouse_logs:/var/log/clickhouse-server healthcheck: test: wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1 interval: 5s timeout: 5s retries: 10 start_period: 10s networks: - WeKnora-network profiles: - langfuse - full langfuse-minio: image: minio/minio:RELEASE.2025-09-07T16-13-09Z container_name: WeKnora-langfuse-minio restart: unless-stopped entrypoint: sh command: -c 'mkdir -p /data/langfuse && minio server --address ":9000" --console-address ":9001" /data' environment: MINIO_ROOT_USER: ${LANGFUSE_MINIO_USER:-langfuseminio} MINIO_ROOT_PASSWORD: ${LANGFUSE_MINIO_PASSWORD:-langfuseminiosecret} ports: - "${LANGFUSE_MINIO_S3_PORT:-9100}:9000" - "${LANGFUSE_MINIO_CONSOLE_PORT:-9101}:9001" volumes: - langfuse_minio_data:/data healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 5s timeout: 10s retries: 5 networks: - WeKnora-network profiles: - langfuse - full langfuse-worker: image: langfuse/langfuse-worker:3 container_name: WeKnora-langfuse-worker restart: unless-stopped depends_on: &langfuse-depends-on langfuse-db-init: condition: service_completed_successfully redis: condition: service_started langfuse-clickhouse: condition: service_healthy langfuse-minio: condition: service_healthy entrypoint: - /bin/sh - -ec - | _enc() { node -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$$1"; } DU=$$(_enc "$$_LF_DB_USER") DP=$$(_enc "$$_LF_DB_PASSWORD") RP=$$(_enc "$$_LF_REDIS_PASSWORD") export DATABASE_URL="postgresql://$$DU:$$DP@postgres:5432/$$_LF_DB_NAME" export REDIS_CONNECTION_STRING="redis://:$$RP@redis:6379/$$_LF_REDIS_DB" unset _LF_DB_USER _LF_DB_PASSWORD _LF_REDIS_PASSWORD exec dumb-init -- ./worker/entrypoint.sh node worker/dist/index.js environment: &langfuse-env _LF_DB_USER: ${DB_USER} _LF_DB_PASSWORD: ${DB_PASSWORD} _LF_DB_NAME: ${LANGFUSE_DB_NAME:-langfuse} _LF_REDIS_PASSWORD: ${REDIS_PASSWORD} _LF_REDIS_DB: ${LANGFUSE_REDIS_DB:-1} SALT: ${LANGFUSE_SALT:-weknora-langfuse-dev-salt-change-me} ENCRYPTION_KEY: ${LANGFUSE_ENCRYPTION_KEY:-0000000000000000000000000000000000000000000000000000000000000000} NEXTAUTH_URL: ${LANGFUSE_NEXTAUTH_URL:-http://localhost:3000} NEXTAUTH_SECRET: ${LANGFUSE_NEXTAUTH_SECRET:-weknora-langfuse-dev-nextauth-secret-change-me} TELEMETRY_ENABLED: ${LANGFUSE_TELEMETRY_ENABLED:-false} LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES: "false" CLICKHOUSE_URL: http://langfuse-clickhouse:8123 CLICKHOUSE_MIGRATION_URL: clickhouse://langfuse-clickhouse:9000 CLICKHOUSE_USER: ${LANGFUSE_CLICKHOUSE_USER:-clickhouse} CLICKHOUSE_PASSWORD: ${LANGFUSE_CLICKHOUSE_PASSWORD:-clickhouse} CLICKHOUSE_CLUSTER_ENABLED: "false" LANGFUSE_S3_EVENT_UPLOAD_BUCKET: langfuse LANGFUSE_S3_EVENT_UPLOAD_REGION: auto LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_USER:-langfuseminio} LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_PASSWORD:-langfuseminiosecret} LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: http://langfuse-minio:9000 LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: "true" LANGFUSE_S3_EVENT_UPLOAD_PREFIX: events/ LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: langfuse LANGFUSE_S3_MEDIA_UPLOAD_REGION: auto LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: ${LANGFUSE_MINIO_USER:-langfuseminio} LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: ${LANGFUSE_MINIO_PASSWORD:-langfuseminiosecret} LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: ${LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT:-http://localhost:9100} LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: "true" LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: media/ networks: - WeKnora-network profiles: - langfuse - full langfuse-web: image: langfuse/langfuse:3 container_name: WeKnora-langfuse-web restart: unless-stopped depends_on: *langfuse-depends-on ports: - "${LANGFUSE_WEB_PORT:-3000}:3000" entrypoint: - /bin/sh - -ec - | _enc() { node -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$$1"; } DU=$$(_enc "$$_LF_DB_USER") DP=$$(_enc "$$_LF_DB_PASSWORD") RP=$$(_enc "$$_LF_REDIS_PASSWORD") export DATABASE_URL="postgresql://$$DU:$$DP@postgres:5432/$$_LF_DB_NAME" export REDIS_CONNECTION_STRING="redis://:$$RP@redis:6379/$$_LF_REDIS_DB" unset _LF_DB_USER _LF_DB_PASSWORD _LF_REDIS_PASSWORD if [ -n "$$NEXT_PUBLIC_LANGFUSE_CLOUD_REGION" ]; then exec dumb-init -- ./web/entrypoint.sh node --import dd-trace/initialize.mjs ./web/server.js --keepAliveTimeout 110000 else exec dumb-init -- ./web/entrypoint.sh node ./web/server.js --keepAliveTimeout 110000 fi environment: <<: *langfuse-env LANGFUSE_INIT_ORG_ID: ${LANGFUSE_INIT_ORG_ID:-} LANGFUSE_INIT_ORG_NAME: ${LANGFUSE_INIT_ORG_NAME:-} LANGFUSE_INIT_PROJECT_ID: ${LANGFUSE_INIT_PROJECT_ID:-} LANGFUSE_INIT_PROJECT_NAME: ${LANGFUSE_INIT_PROJECT_NAME:-} LANGFUSE_INIT_PROJECT_PUBLIC_KEY: ${LANGFUSE_INIT_PROJECT_PUBLIC_KEY:-} LANGFUSE_INIT_PROJECT_SECRET_KEY: ${LANGFUSE_INIT_PROJECT_SECRET_KEY:-} LANGFUSE_INIT_USER_EMAIL: ${LANGFUSE_INIT_USER_EMAIL:-} LANGFUSE_INIT_USER_NAME: ${LANGFUSE_INIT_USER_NAME:-} LANGFUSE_INIT_USER_PASSWORD: ${LANGFUSE_INIT_USER_PASSWORD:-} networks: - WeKnora-network profiles: - langfuse - full # ============================================================ # 18. MCP Server(可选) # 提供 Model Context Protocol 服务,用于外部工具调用 # ============================================================ mcp: build: context: ./mcp-server container_name: WeKnora-mcp ports: - "${MCP_PORT:-8082}:8000" environment: - WEKNORA_BASE_URL=http://app:8080/api/v1 - WEKNORA_API_KEY=${WEKNORA_API_KEY:-} depends_on: app: condition: service_healthy networks: - WeKnora-network restart: unless-stopped profiles: - full

7、点击立即部署;

绿联NAS:搭建WeKnora — 让文档活起来

8、接下来就是漫长的等待,等待完成。。。

9、访问http://你的NAS_IP:28080  ,选择创建账户进行初始化;

绿联NAS:搭建WeKnora — 让文档活起来

10、输入用户名、邮箱、密码、确认密码,点击注册;

绿联NAS:搭建WeKnora — 让文档活起来

11、此时,有成功的喜悦,也有身心的疲惫,项目就搭建好了!!!

绿联NAS:搭建WeKnora — 让文档活起来

三、注意事项:

安全加固:

注册完成后,将.env文件的 DISABLE_REGISTRATION 改回 true 并重启,以阻止后续公开注册。

DISABLE_REGISTRATION=true

四、使用方法和教程

请参考官网:https://weknora.weixin.qq.com/

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
0
扫一下,分享更方便,购买更轻松