一个自托管的多便签 TODO 工具:单账号 JWT 鉴权、浏览器即开即用、macOS ...
2.8K
一个自托管的多便签 TODO 工具:单账号 JWT 鉴权、浏览器即开即用、macOS 原生菜单栏客户端、Windows 原生桌面客户端。
🏠 GitHub • 🐳 Docker Hub • 📦 Releases • 📖 架构文档 • 💬 Issues
github.com/hanxi/stickytododocker.io/hanxi/stickytodo想了解项目架构、模块边界、开发约定?请看 AGENTS.md。
/api/ws):在任一端(浏览器 / macOS 客户端 / Windows 客户端)新建、修改、删除一条 TODO 或便签,其他已登录在线的客户端会在 ~300ms 去抖窗口后自动刷新(客户端侧去抖窗口 + 服务端 hub 即时广播),无需手动按刷新;网络断连后自动指数退避重连并全量拉取%LocalAppData%\stickytodo\frames.json,均不跨端同步(浏览器"便签"本质是 Card 也不需要位置)go:embed 内嵌,零额外静态资源只需按你要用的形态装对应依赖即可,全部都是可选组合。
| 场景 | 依赖 |
|---|---|
| 用 Docker 部署后端 + 浏览器访问 Web UI | Docker 20.10+ 且内置 Compose V2(docker compose 子命令,非旧版 docker-compose 脚本) |
| 本地源码跑后端 | Go 1.25+(与 server/go.mod 对齐) |
| 从源码构建 macOS 客户端 | macOS 13+、完整 Xcode 15+(非 Command Line Tools;仓库在 Xcode 26.4 下验证) |
| 从源码构建 Windows 客户端 | Windows 10 20H1+(10.0.19041)、Visual Studio 2022 的"使用 C++ 的桌面开发"工作负载(提供 MSVC v143 + Windows 10/11 SDK)、CMake ≥ 3.25、Ninja、vcpkg(需把 VCPKG_ROOT 环境变量指向 vcpkg 仓库根);可选 Inno Setup 6(仅为本地打 setup.exe 时需要,缺失可通过 --skip-installer 跳过) |
| 本地开发 Web 客户端 | Node.js 18 / 20 / 22+ 之一、npm(Vite 5 官方只支持 ^18 || ^20 || >=22,奇数 major 不受支持;client/web/package.json 未强制 engines 字段,自行遵守即可) |
💡 JWT 密钥免配置:server 首次启动时生成 32 字节随机熵、hex 编码后(DB 里 64 字符)持久化到 SQLite
app_secrets表的key='jwt_secret'行,重启复用;想强制失效所有 token,删掉该行重启即可。
docker run -d --name stickytodo -p 8080:8080 \
-e TODO_USERNAME=admin \
-e TODO_PASSWORD=change-me-please \
-v $(pwd)/data:/data \
docker.io/hanxi/stickytodo:latest
或使用仓库里的 compose 文件:
cd server
cp .env.example .env # 至少改 TODO_USERNAME / TODO_PASSWORD
docker compose up --build -d # 数据持久化到 server/data/(compose 里是 ./data:/data,
# 以 compose 文件所在目录为基准)
数据落盘位置取决于你在哪个目录跑命令:
docker run -v $(pwd)/data:/data ...存到当前目录下的data/;docker compose存到server/data/(compose 文件自己在server/下)。别混着用,否则换方式启动后会看似"数据丢了"。
官方镜像覆盖 linux/amd64、linux/arm64、linux/arm/v7,由 GitHub Actions 在打 tag 时推送。
cd server
export TODO_USERNAME=admin TODO_PASSWORD=change-me-please # 值与 .env.example 保持一致,便于跑 smoke.sh
go run ./cmd/todo-server
# 默认监听 :8080(0.0.0.0:8080),本机访问 http://127.0.0.1:8080/
# 数据存于 ./data/todo.db(config.go 默认 TODO_DATA_DIR=./data)
⚠️ 仓库里的
server/.env.example是为 Docker Compose 准备的,里面TODO_DATA_DIR=/data指的是容器内路径。如果你本地直接go run,不要source它;需要覆盖数据目录时用export TODO_DATA_DIR=./data(或任意本地绝对路径)。
从 Releases 下载对应平台的二进制(覆盖 linux / darwin / windows × amd64/arm64,以及 linux armv7),先用同目录的 SHA256SUMS 校验完整性:
# 1) 校验下载完整性(和二进制放同一目录,任选其一即可)
sha256sum -c SHA256SUMS # Linux
shasum -a 256 -c SHA256SUMS # macOS(系统自带 shasum)
# 2) macOS / Linux:加执行位
chmod +x stickytodo-server-<version>-<os>-<arch>
# 3) macOS 补充:浏览器下载的产物会带 com.apple.quarantine 扩展属性,首次会被 Gatekeeper 拦
xattr -dr com.apple.quarantine stickytodo-server-<version>-darwin-<arch>
# 4) 运行(数据默认落到当前工作目录的 ./data/,与 Docker 镜像默认 /data 不同)
export TODO_USERNAME=admin TODO_PASSWORD=change-me-please
./stickytodo-server-<version>-<os>-<arch>
Windows 直接双击 .exe 即可;chmod +x 和 xattr 两步仅 Unix 平台需要。
浏览器打开 http://127.0.0.1:8080/app/(结尾斜杠不能少,裸 /app 会 301 重定向到 /app/)。用当前运行的 server 进程所使用的 TODO_USERNAME / TODO_PASSWORD 登录——docker run -e / docker compose 走 .env / go run 走 export,三种起法账号来源不同,不要搞混。
A. 直接下载 DMG(Releases 里的 stickytodo-<version>-macos-universal.dmg)
双击 DMG → 把 stickytodo.app 拖到 /Applications。首次运行会被 Gatekeeper 警告(ad-hoc 签名),右键 App → 打开,确认一次即可。
B. 从源码运行
# 方法 1:Xcode 打开 client/mac/stickytodo.xcodeproj 后 ⌘R
# 方法 2:命令行一键构建
./client/scripts/build.sh
open /tmp/stickytodoBuild/Build/Products/Debug/stickytodo.app
首次使用:应用以菜单栏图标 note.text 常驻(无 Dock 图标)。点图标 → 「打开设置」(⌘,)进入 Settings 窗口。Settings 是 3 Tab 的 macOS Preferences 风格面板:
http://127.0.0.1:8080,可选点「测试连接」验证 → GET /health)→ 登录⋯ 菜单 →「历史」以 sheet 形式打开,作用域仅该条登录后回到菜单栏面板点「新建便签」(⌘N)即可。更多操作 / 快捷键见 client/mac/README.md。
A. 下载安装包或免安装包(Releases 里按架构选一种)
先判断自己的系统架构:Win11 按 Win + Pause 打开"系统信息",看"系统类型"——基于 x64 的处理器 → 下载 x64 版;基于 ARM 的处理器 → 下载 arm64 版(Surface Pro X / Copilot+ PC / 部分笔记本)。不确定时选 x64(Win11 arm64 系统也能通过 x64 emulation 运行)。
stickytodo-setup-<version>-x64.exe / stickytodo-setup-<version>-arm64.exe(Inno Setup 6 安装器,推荐):双击运行,默认 per-user 安装到 %LocalAppData%\Programs\StickyTodo(不弹 UAC);若想装到 %ProgramFiles%\StickyTodo 并供本机所有用户使用,在安装向导勾选"为所有用户安装"(会提示 UAC)。安装器最低要求 Windows 10 20H1(10.0.19041)。arm64 安装器仅能在原生 arm64 Windows 上运行(不接受 x64 emulation),x64 安装器则可在 native x64 和 Win11-arm64 emulation 两种环境下工作。卸载通过"设置 → 应用 → 已安装的应用"或开始菜单里的"Uninstall StickyTodo"(arm64 版在卸载列表里显示为 StickyTodo (arm64) 以便区分)。stickytodo-<version>-windows-x64.zip / stickytodo-<version>-windows-arm64.zip(免安装 portable zip):解压任意目录,直接双击解压后的 stickytodo.exe 运行;不写注册表(除了便签去重确认偏好),便签窗口位置缓存写在 %LocalAppData%\stickytodo\frames.json,JWT token 走 Windows Credential Manager(卸载时若想清理残留,手动删这两处即可)。两种方式均无代码签名,首次运行时 SmartScreen 会弹"Windows 已保护你的电脑"警告,点击"更多信息 → 仍要运行"即可(后续启动不再提示)。下载后建议先用同目录的 SHA256SUMS-<arch> 校验完整性(x64 看 SHA256SUMS-x64,arm64 看 SHA256SUMS-arm64):
# PowerShell(Windows 自带)
Get-FileHash stickytodo-setup-<version>-x64.exe -Algorithm SHA256
# 对比 SHA256SUMS-x64 里对应文件名的那一行即可
B. 从源码构建
在 Git Bash / MSYS2 shell 下执行(需要先让 VCPKG_ROOT 指向本地 vcpkg 仓库根 —— CMD 下用 set VCPKG_ROOT=C:\path\to\vcpkg、PowerShell 下用 $env:VCPKG_ROOT = "C:\path\to\vcpkg"、Git Bash 下用 export VCPKG_ROOT=/c/path/to/vcpkg):
cd client/win
cmake --preset debug # 配置(vcpkg 自动拉 nlohmann-json + cppwinrt + gtest)
cmake --build --preset debug # 编译
./build/debug/stickytodo.exe # 运行
或一键打 portable zip(不需要 Inno Setup):
# 从仓库根,Git Bash / MSYS2 下执行
VERSION=dev bash scripts/package-win-client.sh --skip-installer
# 产物在 dist/win-client/stickytodo-dev-windows-x64.zip
# 要打 arm64 版(从 x64 host 交叉编译,需已激活 amd64_arm64 MSVC 环境):
VERSION=dev ARCH=arm64 bash scripts/package-win-client.sh --skip-installer
# 产物在 dist/win-client/stickytodo-dev-windows-arm64.zip
# 注:本地要走 arm64 交叉编译,需要在 "x64_arm64 Cross Tools Command Prompt"
# 或等价的 vcvarsall.bat amd64_arm64 环境下启动 Git Bash;
# 最省心的方式是让 CI(windows-2022 runner)帮你出 arm64 产物。
首次使用:应用以系统托盘图标(屏幕右下角)常驻,无任务栏入口。右键点击托盘图标(或双击,等价于右键 → Settings)打开托盘菜单;未登录态菜单只有 Settings / Quit 两项,选 Settings 进入设置窗口。设置窗口顶部有 3 个 Tab:Settings / History / About,登录相关表单都在 Settings Tab 下——依次填写服务端地址(Server URL 输入框,例 http://127.0.0.1:8080;可先点 Test Connection 按钮验证 GET /health 可达)、Username、Password,然后点 Login 按钮登录。登录成功后托盘菜单会多出 New Sticky Note / Logout 两项,选 New Sticky Note 即可打开一张便签窗口;History Tab 显示全局审计日志,About Tab 显示版本号等元信息。JWT 经 Windows Credential Manager 加密持久化(target name stickytodo/<username>),关掉客户端再打开会自动登录;便签窗口位置(x/y/width/height)在 %LocalAppData%\stickytodo\frames.json 里自动保存。
全部通过环境变量传入,与后端 .env.example 一致:
| 变量 | 必填 | 默认 | 作用范围 | 说明 |
|---|---|---|---|---|
TODO_USERNAME | ✅ | — | server | 登录用户名 |
TODO_PASSWORD | ✅ | — | server | 登录密码 |
TODO_PORT | ❌ | 8080 | server 进程 | server 进程监听端口(无论跑在裸机、容器还是 docker compose 里,都是进程本身绑定这个端口) |
TODO_HOST_PORT | ❌ | 8080 | docker-compose 宿主机 | 宿主机端口 → 容器内 TODO_PORT 的映射;仅 server/docker-compose.yml 里会用到,裸 docker run 或源码跑都无视此变量 |
TODO_DATA_DIR | ❌ | ./data(源码)/ /data(Docker 镜像) | server | SQLite 存储目录 |
TODO_TOKEN_TTL | ❌ | 24h | server | JWT 有效期(Go time.Duration 格式) |
TODO_CORS_ORIGINS | ❌ | 空(不注入 CORS 中间件) | server | 允许的 Origin allowlist,逗号分隔(精确匹配);特殊值 * 代表放行任意源(见 .env.example 注释) |
TODO_GIN_MODE | ❌ | release | server | debug / release / test |
TODO_VERBOSE | ❌ | false | server | 打开更详细的请求日志(GORM info 级别)。合法取值:1/true/yes/on/t/y(true 集)或 0/false/no/off/f/n(false 集),大小写不敏感;非法值启动时直接报错退出(config.go#parseBoolEnv) |
如果这个项目对你有帮助,欢迎通过以下方式支持:
点击右上角的 ⭐ Star 按钮,让更多人发现这个项目。
MIT
Content type
Image
Digest
sha256:a1a4572b3…
Size
13.7 MB
Last updated
4 months ago
docker pull hanxi/stickytodo