Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81003d3106 | ||
|
|
9aed039702 | ||
|
|
586c4bf049 | ||
|
|
3bbd7a2e1b |
@@ -68,6 +68,7 @@ jobs:
|
||||
bundle = @{
|
||||
active = $true
|
||||
targets = @('nsis')
|
||||
icon = @('icons/icon.png', 'icons/icon.ico')
|
||||
resources = @{
|
||||
'../../.build/sidecar/dist/opennexus-core/' = 'core/'
|
||||
}
|
||||
@@ -75,6 +76,10 @@ jobs:
|
||||
certificateThumbprint = $env:OPENNEXUS_WINDOWS_CERTIFICATE_THUMBPRINT
|
||||
digestAlgorithm = 'sha256'
|
||||
timestampUrl = 'http://timestamp.digicert.com'
|
||||
nsis = @{
|
||||
installerIcon = 'icons/icon.ico'
|
||||
uninstallerIcon = 'icons/icon.ico'
|
||||
}
|
||||
}
|
||||
}
|
||||
} | ConvertTo-Json -Depth 5
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
OpenNexus 是一款本地优先的 AI 笔记与知识中枢。它将 Markdown Vault、全文与向量检索、知识库问答、可审计 Agent、扩展系统和多设备同步整合在一个桌面应用中。笔记与索引由用户掌控;需要模型或同步服务时,再按需连接本地或远程服务。
|
||||
|
||||
当前发布版本为 **0.3.1-alpha.2**,主要支持 Windows x64。Alpha 版本仍处于快速迭代阶段,升级前请备份 Vault。
|
||||
当前发布版本为 **0.3.2-alpha.1**,主要支持 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.2-alpha.1 发布页](https://gitea.kronecker.cc/Kronecker/NotesAgentic/releases/tag/v0.3.2-alpha.1)。发布页同时附带 `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 可能显示未知发布者提示。
|
||||
|
||||
## 参与开发
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#171717" />
|
||||
<link rel="icon" type="image/svg+xml" href="/opennexus-logo.svg" />
|
||||
<title>OpenNexus</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "notes-agent-frontend",
|
||||
"private": true,
|
||||
"version": "0.3.1-alpha.2",
|
||||
"version": "0.3.2-alpha.1",
|
||||
"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",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
|
||||
<title id="title">OpenNexus</title>
|
||||
<desc id="desc">蓝紫色线框文档标志</desc>
|
||||
<rect x="12" y="12" width="1000" height="1000" rx="252" fill="#fbfcff" stroke="#e1e5f0" stroke-width="24"/>
|
||||
<path d="M254 184h322l194 194v462H254z" fill="none" stroke="#6269f6" stroke-width="48" stroke-linejoin="round"/>
|
||||
<path d="M576 184v194h194" fill="none" stroke="#6269f6" stroke-width="48" stroke-linejoin="round"/>
|
||||
<path d="M382 508h260M382 622h260M382 736h260" fill="none" stroke="#6269f6" stroke-width="42" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 651 B |
Generated
+1
-1
@@ -3242,7 +3242,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "notesagent-desktop"
|
||||
version = "0.3.1-alpha.2"
|
||||
version = "0.3.2-alpha.1"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"base64 0.22.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "notesagent-desktop"
|
||||
version = "0.3.1-alpha.2"
|
||||
version = "0.3.2-alpha.1"
|
||||
edition = "2021"
|
||||
rust-version = "1.89"
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
@@ -1,7 +1,39 @@
|
||||
{
|
||||
"$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.png",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "OpenNexus",
|
||||
"version": "0.3.1-alpha.2",
|
||||
"version": "0.3.2-alpha.1",
|
||||
"identifier": "cc.kronecker.notesagent",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
@@ -10,11 +10,30 @@
|
||||
"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,
|
||||
"icon": [
|
||||
"icons/icon.png",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc">
|
||||
<title id="title">OpenNexus</title>
|
||||
<desc id="desc">蓝紫色线框文档标志</desc>
|
||||
<rect x="12" y="12" width="1000" height="1000" rx="252" fill="#fbfcff" stroke="#e1e5f0" stroke-width="24"/>
|
||||
<path d="M254 184h322l194 194v462H254z" fill="none" stroke="#6269f6" stroke-width="48" stroke-linejoin="round"/>
|
||||
<path d="M576 184v194h194" fill="none" stroke="#6269f6" stroke-width="48" stroke-linejoin="round"/>
|
||||
<path d="M382 508h260M382 622h260M382 736h260" fill="none" stroke="#6269f6" stroke-width="42" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 651 B |
@@ -6,6 +6,7 @@ import { useEditorStore } from '@/stores/editor'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { Moon, Sunny } from '@element-plus/icons-vue'
|
||||
import AppIcon from './AppIcon.vue'
|
||||
import appLogoUrl from '@/assets/opennexus-logo.svg'
|
||||
import { t } from '@/i18n'
|
||||
import { isDesktop } from '@/services/platform/desktop'
|
||||
import { minimizeWindow, requestWindowClose, toggleMaximizeWindow } from '@/services/platform/windowControls'
|
||||
@@ -63,7 +64,7 @@ function toggleFromTitlebar(event: MouseEvent) {
|
||||
</span>
|
||||
</div>
|
||||
<div class="titlebar-center" data-tauri-drag-region>
|
||||
<span class="app-name" data-tauri-drag-region>OpenNexus</span>
|
||||
<span class="app-name" data-tauri-drag-region><img :src="appLogoUrl" alt="" />OpenNexus</span>
|
||||
</div>
|
||||
<div class="titlebar-right">
|
||||
<button class="icon-btn" @click="themeStore.toggleTheme()" :title="themeStore.isDark ? t('切换浅色主题', 'Switch to light theme') : t('切换深色主题', 'Switch to dark theme')">
|
||||
@@ -142,6 +143,9 @@ function toggleFromTitlebar(event: MouseEvent) {
|
||||
}
|
||||
|
||||
.app-name {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 3px 10px;
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-full);
|
||||
@@ -151,6 +155,11 @@ function toggleFromTitlebar(event: MouseEvent) {
|
||||
letter-spacing: .04em;
|
||||
}
|
||||
|
||||
.app-name img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.titlebar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -4,8 +4,9 @@ import { useRouter } from 'vue-router'
|
||||
import { useWorkspaceStore } from '@/stores/workspace'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useSettingsStore } from '@/stores/settings'
|
||||
import { ArrowRight, Document, Folder, FolderOpened, Moon, Sunny } from '@element-plus/icons-vue'
|
||||
import { ArrowRight, Folder, FolderOpened, Moon, Sunny } from '@element-plus/icons-vue'
|
||||
import AppIcon from '@/components/common/AppIcon.vue'
|
||||
import appLogoUrl from '@/assets/opennexus-logo.svg'
|
||||
import { t } from '@/i18n'
|
||||
import { ApiErrorClass } from '@/services/apiClient'
|
||||
import { isDesktop } from '@/services/platform/desktop'
|
||||
@@ -62,7 +63,7 @@ async function openFolderPicker() {
|
||||
<div class="bg-decoration" />
|
||||
<div class="entry-container">
|
||||
<div class="brand-section">
|
||||
<div class="logo"><AppIcon :icon="Document" :size="56" /></div>
|
||||
<div class="logo"><img :src="appLogoUrl" alt="" /></div>
|
||||
<h1 class="app-title">OpenNexus</h1>
|
||||
<p class="app-subtitle">{{ t('本地优先的 AI 笔记软件', 'A local-first AI note-taking app') }}</p>
|
||||
</div>
|
||||
@@ -109,7 +110,7 @@ async function openFolderPicker() {
|
||||
</div>
|
||||
|
||||
<div class="footer-info">
|
||||
<span>v0.1.0</span>
|
||||
<span>v0.3.2-alpha.1</span>
|
||||
<button class="theme-toggle" @click="themeStore.toggleTheme()">
|
||||
<AppIcon :icon="themeStore.isDark ? Sunny : Moon" :size="15" />
|
||||
{{ themeStore.isDark ? t('浅色', 'Light') : t('深色', 'Dark') }}
|
||||
@@ -164,13 +165,15 @@ async function openFolderPicker() {
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
margin-bottom: 14px;
|
||||
border: 1px solid color-mix(in srgb, var(--color-accent-primary) 18%, transparent);
|
||||
border-radius: 24px;
|
||||
background: var(--color-surface-primary);
|
||||
color: var(--color-accent-primary);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.logo img {
|
||||
display: block;
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -6,7 +6,7 @@ import paper from '@/assets/themes/paper-moments.theme?raw'
|
||||
|
||||
afterEach(() => vi.unstubAllGlobals())
|
||||
it('uses the desktop release version for compatibility checks', () => {
|
||||
expect(THEME_APP_VERSION).toBe('0.3.1-alpha.2')
|
||||
expect(THEME_APP_VERSION).toBe('0.3.2-alpha.1')
|
||||
})
|
||||
it.each(['999.0.0', 'bad', '0.2'])('rejects unsupported minimum app version %s at inspection and install', async version => {
|
||||
const source = paper.replace(/min_app_version:.*\r?\n/, `min_app_version: ${version}\n`)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -7,6 +7,10 @@ COPY console ./
|
||||
RUN pnpm build
|
||||
|
||||
FROM python:3.12-slim
|
||||
ARG OPENNEXUS_SYNC_VERSION=0.3.2-alpha.1
|
||||
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"]
|
||||
|
||||
+20
-4
@@ -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.2-alpha.1**。协议及限制见 [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.2-alpha.1.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 通过 IPv4 与 IPv6 暴露到 `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.2-alpha.1 使用真实 PostgreSQL/MinIO 环境验证初始化、重复启动、固定凭据、健康检查和已有数据升级。测试专用 HTTP 地址、故障检查、完整验收记录与运维入口见[验收报告](../docs/development/OpenNexus验收报告-2026-09-08.md)。S-07 已在原生 PostgreSQL 17.11/MinIO 实例完成 1 GiB/10,000 文件的删除源实例与空实例恢复。测试阶段可以直接开放 HTTP 端口;生产上线仍需配置 TLS、访问控制、监控与异机备份。
|
||||
|
||||
## 备份与空实例恢复
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# 仅用于隔离的明文 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"
|
||||
- "[::]:${SYNC_PORT:-18080}:8080"
|
||||
restart: unless-stopped
|
||||
@@ -20,12 +20,16 @@ services:
|
||||
volumes:
|
||||
- objects:/data
|
||||
initialize:
|
||||
build: .
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
OPENNEXUS_SYNC_VERSION: ${OPENNEXUS_SYNC_TAG:-0.3.2-alpha.1}
|
||||
image: opennexus-sync:${OPENNEXUS_SYNC_TAG:-0.3.2-alpha.1}
|
||||
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.2-alpha.1}
|
||||
image: opennexus-sync:${OPENNEXUS_SYNC_TAG:-0.3.2-alpha.1}
|
||||
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:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "opennexus-sync-console",
|
||||
"private": true,
|
||||
"version": "0.3.1-alpha.2",
|
||||
"version": "0.3.2-alpha.1",
|
||||
"packageManager": "pnpm@10.28.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "notesagent-sync"
|
||||
version = "0.3.1a2"
|
||||
version = "0.3.2a1"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"fastapi>=0.116,<1", "uvicorn>=0.35,<1", "sqlalchemy>=2.0,<2.1",
|
||||
|
||||
Generated
+1
-1
@@ -225,7 +225,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "notesagent-sync"
|
||||
version = "0.3.1a2"
|
||||
version = "0.3.2a1"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "boto3" },
|
||||
|
||||
Reference in New Issue
Block a user