From 586c4bf049ee4c36e217cf233d0e010cd57570b1 Mon Sep 17 00:00:00 2001 From: KiriAky 107 Date: Tue, 15 Sep 2026 10:50:12 +0800 Subject: [PATCH] =?UTF-8?q?build(release):=20=E5=87=86=E5=A4=870.3.1-alpha?= =?UTF-8?q?.3=E5=AE=89=E8=A3=85=E5=8C=85=E4=B8=8EDocker=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 31 ++++++++++++++------ frontend/package.json | 4 +-- frontend/src-tauri/Cargo.lock | 2 +- frontend/src-tauri/Cargo.toml | 2 +- frontend/src-tauri/tauri.bundle.conf.json | 35 +++++++++++++++++++++-- frontend/src-tauri/tauri.conf.json | 23 ++++++++++++--- server sync/.dockerignore | 19 ++++++++++++ server sync/.env.example | 2 ++ server sync/Dockerfile | 5 ++++ server sync/README.md | 24 +++++++++++++--- server sync/compose.test.yaml | 9 ++++++ server sync/compose.yaml | 22 +++++++++++--- server sync/console/package.json | 2 +- server sync/pyproject.toml | 2 +- server sync/uv.lock | 2 +- 15 files changed, 155 insertions(+), 29 deletions(-) create mode 100644 server sync/.dockerignore create mode 100644 server sync/compose.test.yaml diff --git a/README.md b/README.md index a808af4..f5336a9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ OpenNexus 是一款本地优先的 AI 笔记与知识中枢。它将 Markdown Vault、全文与向量检索、知识库问答、可审计 Agent、扩展系统和多设备同步整合在一个桌面应用中。笔记与索引由用户掌控;需要模型或同步服务时,再按需连接本地或远程服务。 -当前发布版本为 **0.3.1-alpha.2**,主要支持 Windows x64。Alpha 版本仍处于快速迭代阶段,升级前请备份 Vault。 +当前发布版本为 **0.3.1-alpha.3**,主要支持 Windows x64。Alpha 版本仍处于快速迭代阶段,升级前请备份 Vault。 ## 主要能力 @@ -34,13 +34,13 @@ flowchart LR ## 使用发布包 -本版提供 Windows x64 便携包和独立的 Server Sync 包,下载入口见 [v0.3.1-alpha.2 发布页](https://gitea.kronecker.cc/Kronecker/NotesAgentic/releases/tag/v0.3.1-alpha.2)。发布页同时附带 `SHA256.json`,用于核对文件完整性。 +本版提供 Windows x64 EXE 安装包和独立的 Server Sync 包,下载入口见 [v0.3.1-alpha.3 发布页](https://gitea.kronecker.cc/Kronecker/NotesAgentic/releases/tag/v0.3.1-alpha.3)。发布页同时附带 `SHA256.json`,用于核对文件完整性。 -便携包是干净的首次安装环境,不包含任何 Vault 或用户数据,也不预装已下载的社区主题、本地模型权重、CUDA 与 PyTorch 运行时。相关功能仍完整保留;需要时可在客户端内按需安装主题、选择模型或配置 CUDA 环境。程序自带的基础界面样式属于客户端资源,不视为社区主题。 +安装包不包含任何 Vault 或用户数据,也不预装已下载的社区主题、本地模型权重、CUDA 与 PyTorch 运行时。相关功能仍完整保留;需要时可在客户端内按需安装主题、选择模型或配置 CUDA 环境。程序自带的基础界面样式属于客户端资源,不视为社区主题。同一 Windows 用户下升级安装会继续使用 `%APPDATA%\cc.kronecker.notesagent` 中的既有配置和索引,以及用户此前选择的外部 Vault。 -1. 下载 Windows x64 软件包,并核对发布页中的 SHA-256。 -2. 将便携版完整解压到可写目录,不要单独移动可执行文件。 -3. 启动 `OpenNexus.exe`,选择已有 Vault 或创建新 Vault。 +1. 下载 Windows x64 EXE 安装包,并核对发布页中的 SHA-256。 +2. 运行安装程序,按向导完成当前用户安装;未签名的 Alpha 包可能触发 Windows 未知发布者提示。 +3. 从开始菜单启动 OpenNexus,选择已有 Vault 或创建新 Vault。 4. 在“设置 → 模型提供商”中配置本地模型或远程模型凭据。 5. 如需多设备同步,在同步设置中填写管理员提供的 Sync Server 地址并登录。 @@ -124,7 +124,22 @@ Gitea Actions 会在推送和合并请求时执行文档检查、后端测试、 ## 部署 Sync Server -开发或内网验证可直接运行: +推荐使用 Docker Compose 启动 PostgreSQL、MinIO 和 Sync: + +```powershell +cd "server sync" +Copy-Item .env.example .env +# 编辑 .env 并生成各项独立密钥 +docker compose up -d --build +``` + +隔离测试阶段如需直接开放 `18080` 明文端口,可使用 Docker Compose 2.24.4 或更高版本加载测试覆盖文件: + +```powershell +docker compose -f compose.yaml -f compose.test.yaml up -d --build +``` + +不使用容器的开发联调也可直接运行: ```powershell cd "server sync" @@ -162,7 +177,7 @@ OpenNexus/ OpenNexus 将 Vault 内容、模型凭据和扩展权限视为敏感数据。请只安装可信来源的 Skill、Plugin 与主题包,并在授权前检查其权限。服务端部署不得使用示例密钥或开发数据库。 -正式发行物通过 Git 标签追踪,并在发布页提供校验和。Windows 安装包的生产门禁还会验证 Authenticode 和 Core 清单签名。本版提供的便携包尚未进行 Authenticode 签名,Windows 可能显示未知发布者提示。 +正式发行物通过 Git 标签追踪,并在发布页提供校验和。Windows 安装包的生产门禁还会验证 Authenticode 和 Core 清单签名。本版 EXE 安装包尚未进行 Authenticode 签名,Windows 可能显示未知发布者提示。 ## 参与开发 diff --git a/frontend/package.json b/frontend/package.json index a7e59ba..847b5af 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,12 +1,12 @@ { "name": "notes-agent-frontend", "private": true, - "version": "0.3.1-alpha.2", + "version": "0.3.1-alpha.3", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", - "desktop:build": "tauri build --no-bundle --features desktop", + "desktop:build": "tauri build --features desktop --bundles nsis --config src-tauri/tauri.bundle.conf.json", "test": "vitest run", "preview": "vite preview", "type-check": "vue-tsc --noEmit -p tsconfig.app.json && vue-tsc --noEmit -p tsconfig.node.json", diff --git a/frontend/src-tauri/Cargo.lock b/frontend/src-tauri/Cargo.lock index 9f8b35d..861a4a0 100644 --- a/frontend/src-tauri/Cargo.lock +++ b/frontend/src-tauri/Cargo.lock @@ -3242,7 +3242,7 @@ dependencies = [ [[package]] name = "notesagent-desktop" -version = "0.3.1-alpha.2" +version = "0.3.1-alpha.3" dependencies = [ "argon2", "base64 0.22.1", diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml index 6a3e8db..01978be 100644 --- a/frontend/src-tauri/Cargo.toml +++ b/frontend/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "notesagent-desktop" -version = "0.3.1-alpha.2" +version = "0.3.1-alpha.3" edition = "2021" rust-version = "1.89" diff --git a/frontend/src-tauri/tauri.bundle.conf.json b/frontend/src-tauri/tauri.bundle.conf.json index 3704a3f..dfb4f23 100644 --- a/frontend/src-tauri/tauri.bundle.conf.json +++ b/frontend/src-tauri/tauri.bundle.conf.json @@ -1,7 +1,38 @@ { + "$schema": "https://schema.tauri.app/config/2", "bundle": { "active": true, - "targets": ["nsis"], - "resources": {"../../.build/sidecar/dist/opennexus-core/": "core/"} + "targets": [ + "nsis" + ], + "publisher": "Kronecker", + "homepage": "https://gitea.kronecker.cc/Kronecker/NotesAgentic", + "icon": [ + "icons/icon.ico" + ], + "resources": { + "../../.build/sidecar/dist/opennexus-core/": "core/" + }, + "category": "Productivity", + "shortDescription": "本地优先的 AI 笔记与知识中枢", + "windows": { + "allowDowngrades": false, + "webviewInstallMode": { + "type": "downloadBootstrapper", + "silent": true + }, + "nsis": { + "installMode": "currentUser", + "languages": [ + "SimpChinese", + "English" + ], + "displayLanguageSelector": false, + "compression": "lzma", + "installerIcon": "icons/icon.ico", + "uninstallerIcon": "icons/icon.ico", + "startMenuFolder": "OpenNexus" + } + } } } diff --git a/frontend/src-tauri/tauri.conf.json b/frontend/src-tauri/tauri.conf.json index a4d434e..b8df104 100644 --- a/frontend/src-tauri/tauri.conf.json +++ b/frontend/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "OpenNexus", - "version": "0.3.1-alpha.2", + "version": "0.3.1-alpha.3", "identifier": "cc.kronecker.notesagent", "build": { "beforeDevCommand": "pnpm dev", @@ -10,11 +10,26 @@ "frontendDist": "../dist" }, "app": { - "windows": [{"label": "main", "title": "OpenNexus", "width": 1280, "height": 960, "minWidth": 720, "minHeight": 700, "center": true, "decorations": false}], + "windows": [ + { + "label": "main", + "title": "OpenNexus", + "width": 1280, + "height": 960, + "minWidth": 720, + "minHeight": 700, + "center": true, + "decorations": false + } + ], "security": { "csp": "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; connect-src ipc: http://ipc.localhost; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", - "capabilities": ["main"] + "capabilities": [ + "main" + ] } }, - "bundle": {"active": false} + "bundle": { + "active": false + } } diff --git a/server sync/.dockerignore b/server sync/.dockerignore new file mode 100644 index 0000000..39a3f5f --- /dev/null +++ b/server sync/.dockerignore @@ -0,0 +1,19 @@ +.env +.env.* +!.env.example +.git +.gitea +.venv +__pycache__ +*.py[cod] +.pytest_cache +.ruff_cache +console/node_modules +console/dist +tests +tools +backups +data +vault +*.sqlite* +*.db diff --git a/server sync/.env.example b/server sync/.env.example index c92751e..0a9ad9a 100644 --- a/server sync/.env.example +++ b/server sync/.env.example @@ -1,10 +1,12 @@ # 所有值由部署维护者生成;数据库 URL 中密码须进行 URL 编码。 +OPENNEXUS_SYNC_TAG=0.3.1-alpha.3 POSTGRES_PASSWORD= SYNC_DATABASE_URL= MINIO_ROOT_USER= MINIO_ROOT_PASSWORD= SYNC_ACCESS_KEY_ID= SYNC_SECRET_ACCESS_KEY= +SYNC_S3_BUCKET=opennexus # 默认只监听本机;仅在已隔离的明文 HTTP 测试阶段显式改为 0.0.0.0。 SYNC_BIND_ADDRESS=127.0.0.1 SYNC_PORT=8080 diff --git a/server sync/Dockerfile b/server sync/Dockerfile index a4c3ad1..5451f96 100644 --- a/server sync/Dockerfile +++ b/server sync/Dockerfile @@ -7,6 +7,10 @@ COPY console ./ RUN pnpm build FROM python:3.12-slim +ARG OPENNEXUS_SYNC_VERSION=0.3.1-alpha.3 +LABEL org.opencontainers.image.title="OpenNexus Server Sync" \ + org.opencontainers.image.version="${OPENNEXUS_SYNC_VERSION}" \ + org.opencontainers.image.source="https://gitea.kronecker.cc/Kronecker/NotesAgentic" COPY --from=ghcr.io/astral-sh/uv:0.9.24 /uv /bin/uv WORKDIR /service COPY pyproject.toml uv.lock ./ @@ -16,4 +20,5 @@ COPY --from=console /sync_server/static ./sync_server/static RUN useradd --uid 10001 --create-home opennexus && mkdir /staging && chown opennexus /staging USER 10001 ENV SYNC_STAGING_DIR=/staging +EXPOSE 8080 CMD ["/service/.venv/bin/python", "-m", "sync_server", "serve"] diff --git a/server sync/README.md b/server sync/README.md index f701155..cd04acc 100644 --- a/server sync/README.md +++ b/server sync/README.md @@ -1,6 +1,6 @@ # OpenNexus Server Sync -当前发布版本为 **0.3.1-alpha.2**。协议及限制见 [Sync v1](../docs/contracts/Sync-v1契约.md)。服务独立于 AI Core,生产入口仅支持 PostgreSQL 和 S3 兼容对象存储。独立发布包包含服务源码、锁文件、Vue 3 + TypeScript 管理控制台静态文件、Dockerfile 与 Compose 模板,不包含任何 Vault、账户数据库、对象存储数据或部署密钥。 +当前发布版本为 **0.3.1-alpha.3**。协议及限制见 [Sync v1](../docs/contracts/Sync-v1契约.md)。服务独立于 AI Core,生产入口仅支持 PostgreSQL 和 S3 兼容对象存储。独立发布包包含服务源码、锁文件、Vue 3 + TypeScript 管理控制台静态文件、Dockerfile 与 Compose 模板,不包含任何 Vault、账户数据库、对象存储数据或部署密钥。 服务根路径 `/` 与 `/console/` 提供同源的 Vue 3 + TypeScript Sync Console,可查看服务健康与依赖就绪状态,并使用普通 Sync 账户管理自己的 Vault 和设备。页面只调用公开的 Sync v1 API;密码在请求发出前从输入框清除,访问和刷新令牌只保留在页面内存,刷新或关闭页面即丢弃。控制台源码位于 `console/`,生产静态文件由 Docker 多阶段构建生成。 @@ -22,9 +22,25 @@ uv run pytest ## 自托管准备 -从发布页下载 `OpenNexus-Server-Sync-0.3.1-alpha.2.zip` 并核对 `SHA256.json` 后,将压缩包解压到独立目录。升级现有实例时先备份数据库、对象存储和 `.env`,再使用新版镜像替换 Sync 服务;不要用发行包覆盖持久化卷。 +从发布页下载 `OpenNexus-Server-Sync-0.3.1-alpha.3.zip` 并核对 `SHA256.json` 后,将压缩包解压到独立目录。升级现有实例时先备份数据库、对象存储和 `.env`,再使用新版镜像替换 Sync 服务;不要用发行包覆盖持久化卷。 -1. 将 `.env.example` 复制为 `.env`,生成独立数据库、MinIO 管理和同步访问凭据。数据库 URL 使用 `postgresql+psycopg://…`,其中密码须 URL 编码。 +仓库提供以下 Docker 文件: + +- `Dockerfile`:构建 Vue 控制台和只读运行镜像。 +- `compose.yaml`:启动 PostgreSQL、MinIO、一次性初始化任务和 Sync 服务,默认只监听 `127.0.0.1:8080`。 +- `compose.test.yaml`:仅供隔离验收使用,将 Sync 暴露到 `0.0.0.0:18080` 并使用 MinIO 管理凭据。 +- `.dockerignore`:排除密钥、数据库、Vault、测试缓存和本机依赖。 + +```powershell +Copy-Item .env.example .env +# 编辑 .env 后启动生产形态 +docker compose up -d --build + +# 或在隔离测试机直接开放 18080;需要 Docker Compose 2.24.4+ +docker compose -f compose.yaml -f compose.test.yaml up -d --build +``` + +1. 将 `.env.example` 复制为 `.env`,生成独立数据库、MinIO 管理和同步访问凭据。数据库 URL 使用 `postgresql+psycopg://…`,其中密码须 URL 编码。升级现有实例时,将 `SYNC_S3_BUCKET` 保持为原实例的 Bucket 名称。 2. 执行 `docker compose up -d`。一次性 `initialize` 服务等待依赖后幂等创建 schema 与 `opennexus` Bucket;重复运行只检查并补齐缺失资源,不覆盖已有行或对象。长期运行的 `sync` 服务继续使用只限该 Bucket 的同步账号,不使用 MinIO root 身份。 3. 全新数据库会生成账户 `admin` 和本次启动专用的随机密码。使用 `docker compose logs sync` 查找 `SYNC_BOOTSTRAP_CREDENTIALS`;随机密码不会写入镜像、环境变量或数据库明文。只要账户尚未固定,服务每次重启都会更换该密码并撤销旧会话。 4. 使用随机密码首次登录控制台后,必须立即修改账户名和密码。保存成功后凭据写入数据库,此后服务重启不再更换。已有正式账户的升级实例不会额外创建默认账户。仍可使用 `create-user` 运维命令增加独立账户,密码通过终端交互输入。 @@ -41,7 +57,7 @@ docker compose run --rm sync /service/.venv/bin/python -m sync_server bootstrap- `initialize` 命令已通过真实 PostgreSQL/MinIO 的空实例与重复运行验证,并由 Compose 的一次性服务调用。MinIO 同步账号仍须由管理员创建并限制到 `opennexus` Bucket,`.env` 中的 root 与同步凭据必须不同。 -0.3.1-alpha.2 已使用真实 PostgreSQL/MinIO 双 worker 环境验证初始化、重复启动、固定凭据、健康检查和已有数据升级。测试专用 HTTP 地址、故障检查、完整验收记录与运维入口见[验收报告](../docs/development/OpenNexus验收报告-2026-09-08.md)。S-07 已在原生 PostgreSQL 17.11/MinIO 实例完成 1 GiB/10,000 文件的删除源实例与空实例恢复。测试阶段可以直接开放 HTTP 端口;生产上线仍需配置 TLS、访问控制、监控与异机备份。 +0.3.1-alpha.3 使用真实 PostgreSQL/MinIO 环境验证初始化、重复启动、固定凭据、健康检查和已有数据升级。测试专用 HTTP 地址、故障检查、完整验收记录与运维入口见[验收报告](../docs/development/OpenNexus验收报告-2026-09-08.md)。S-07 已在原生 PostgreSQL 17.11/MinIO 实例完成 1 GiB/10,000 文件的删除源实例与空实例恢复。测试阶段可以直接开放 HTTP 端口;生产上线仍需配置 TLS、访问控制、监控与异机备份。 ## 备份与空实例恢复 diff --git a/server sync/compose.test.yaml b/server sync/compose.test.yaml new file mode 100644 index 0000000..1c6ee1d --- /dev/null +++ b/server sync/compose.test.yaml @@ -0,0 +1,9 @@ +# 仅用于隔离的明文 HTTP 验收环境;生产部署不要加载此覆盖文件。 +services: + sync: + environment: + AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER:?required} + AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?required} + ports: !override + - "0.0.0.0:${SYNC_PORT:-18080}:8080" + restart: unless-stopped diff --git a/server sync/compose.yaml b/server sync/compose.yaml index f7bc5a2..8433b30 100644 --- a/server sync/compose.yaml +++ b/server sync/compose.yaml @@ -20,12 +20,16 @@ services: volumes: - objects:/data initialize: - build: . + build: + context: . + args: + OPENNEXUS_SYNC_VERSION: ${OPENNEXUS_SYNC_TAG:-0.3.1-alpha.3} + image: opennexus-sync:${OPENNEXUS_SYNC_TAG:-0.3.1-alpha.3} command: ["/service/.venv/bin/python", "-m", "sync_server", "initialize"] environment: SYNC_DATABASE_URL: ${SYNC_DATABASE_URL:?required} SYNC_S3_ENDPOINT: http://objects:9000 - SYNC_S3_BUCKET: opennexus + SYNC_S3_BUCKET: ${SYNC_S3_BUCKET:-opennexus} AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER:?required} AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:?required} AWS_DEFAULT_REGION: us-east-1 @@ -36,11 +40,15 @@ services: condition: service_started restart: "no" sync: - build: . + build: + context: . + args: + OPENNEXUS_SYNC_VERSION: ${OPENNEXUS_SYNC_TAG:-0.3.1-alpha.3} + image: opennexus-sync:${OPENNEXUS_SYNC_TAG:-0.3.1-alpha.3} environment: SYNC_DATABASE_URL: ${SYNC_DATABASE_URL:?required} SYNC_S3_ENDPOINT: http://objects:9000 - SYNC_S3_BUCKET: opennexus + SYNC_S3_BUCKET: ${SYNC_S3_BUCKET:-opennexus} AWS_ACCESS_KEY_ID: ${SYNC_ACCESS_KEY_ID:?required} AWS_SECRET_ACCESS_KEY: ${SYNC_SECRET_ACCESS_KEY:?required} AWS_DEFAULT_REGION: us-east-1 @@ -57,6 +65,12 @@ services: security_opt: - no-new-privileges:true cap_drop: [ALL] + healthcheck: + test: ["CMD", "/service/.venv/bin/python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/ready', timeout=3).read()"] + interval: 15s + timeout: 5s + retries: 8 + start_period: 20s volumes: postgres: objects: diff --git a/server sync/console/package.json b/server sync/console/package.json index 4fc7369..f14ed4a 100644 --- a/server sync/console/package.json +++ b/server sync/console/package.json @@ -1,7 +1,7 @@ { "name": "opennexus-sync-console", "private": true, - "version": "0.3.1-alpha.2", + "version": "0.3.1-alpha.3", "packageManager": "pnpm@10.28.0", "type": "module", "scripts": { diff --git a/server sync/pyproject.toml b/server sync/pyproject.toml index 127c0b8..9e78089 100644 --- a/server sync/pyproject.toml +++ b/server sync/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "notesagent-sync" -version = "0.3.1a2" +version = "0.3.1a3" requires-python = ">=3.12" dependencies = [ "fastapi>=0.116,<1", "uvicorn>=0.35,<1", "sqlalchemy>=2.0,<2.1", diff --git a/server sync/uv.lock b/server sync/uv.lock index a73b3a1..7373c8e 100644 --- a/server sync/uv.lock +++ b/server sync/uv.lock @@ -225,7 +225,7 @@ wheels = [ [[package]] name = "notesagent-sync" -version = "0.3.1a2" +version = "0.3.1a3" source = { virtual = "." } dependencies = [ { name = "boto3" },