Sign inSign up

hanxi/stickytodo

By hanxi

Updated 4 months ago

一个自托管的多便签 TODO 工具:单账号 JWT 鉴权、浏览器即开即用、macOS ...

Image
0

2.8K

hanxi/stickytodo repository overview

stickytodo

GitHub License GitHub Release Docker Image Version Docker Pulls Go Version GitHub Stars GitHub Forks GitHub Issues GitHub last commit Daily Visitors Total Visitors

一个自托管的多便签 TODO 工具:单账号 JWT 鉴权、浏览器即开即用、macOS 原生菜单栏客户端、Windows 原生桌面客户端。

🏠 GitHub🐳 Docker Hub📦 Releases📖 架构文档💬 Issues

  • GitHub:github.com/hanxi/stickytodo
  • Docker:docker.io/hanxi/stickytodo

想了解项目架构、模块边界、开发约定?请看 AGENTS.md

功能一览

  • 单账号登录(用户名 / 密码通过环境变量配置)
  • TODO 增删改 / 完成 / 软删除 / 恢复
  • 单条 TODO 变更历史 + 全局操作审计日志
  • 多便签:Web 网格布局 / macOS 每便签一窗 / Windows 每便签一窗(Win32 + Direct2D 原生自绘),支持独立筛选、颜色、置顶
  • 跨端实时同步(WebSocket /api/ws):在任一端(浏览器 / macOS 客户端 / Windows 客户端)新建、修改、删除一条 TODO 或便签,其他已登录在线的客户端会在 ~300ms 去抖窗口后自动刷新(客户端侧去抖窗口 + 服务端 hub 即时广播),无需手动按刷新;网络断连后自动指数退避重连并全量拉取
  • 便签本身跨端同步(服务端是唯一数据源);macOS 端的便签窗口位置仅保存在本机 UserDefaults、Windows 端的便签窗口位置仅保存在本机 %LocalAppData%\stickytodo\frames.json,均不跨端同步(浏览器"便签"本质是 Card 也不需要位置)
  • 后端单二进制部署,Web UI 通过 go:embed 内嵌,零额外静态资源

前置依赖

只需按你要用的形态装对应依赖即可,全部都是可选组合

场景依赖
用 Docker 部署后端 + 浏览器访问 Web UIDocker 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,删掉该行重启即可。

安装和运行

方式 A:Docker(推荐)
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/amd64linux/arm64linux/arm/v7,由 GitHub Actions 在打 tag 时推送。

方式 B:源码直接跑后端
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(或任意本地绝对路径)。

方式 C:预编译二进制

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 +xxattr 两步仅 Unix 平台需要。

访问 Web UI

浏览器打开 http://127.0.0.1:8080/app/(结尾斜杠不能少,裸 /app 会 301 重定向到 /app/)。用当前运行的 server 进程所使用的 TODO_USERNAME / TODO_PASSWORD 登录——docker run -e / docker compose.env / go runexport,三种起法账号来源不同,不要搞混。

运行 macOS 客户端

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 风格面板

  • 「设置」Tab:填服务端地址(如 http://127.0.0.1:8080,可选点「测试连接」验证 → GET /health)→ 登录
  • 「历史」Tab:登录后查看全局审计日志(菜单栏面板里已不再有「历史」按钮,全局入口只在此处)。单条 TODO 的变更历史仍可通过便签窗口内 TODO 行末尾的 菜单 →「历史」以 sheet 形式打开,作用域仅该条
  • 「关于」Tab:版本号 / Bundle ID / 项目链接

登录后回到菜单栏面板点「新建便签」(⌘N)即可。更多操作 / 快捷键见 client/mac/README.md

运行 Windows 客户端

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 可达)、UsernamePassword,然后点 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_USERNAMEserver登录用户名
TODO_PASSWORDserver登录密码
TODO_PORT8080server 进程server 进程监听端口(无论跑在裸机、容器还是 docker compose 里,都是进程本身绑定这个端口)
TODO_HOST_PORT8080docker-compose 宿主机宿主机端口 → 容器内 TODO_PORT 的映射; server/docker-compose.yml 里会用到,裸 docker run 或源码跑都无视此变量
TODO_DATA_DIR./data(源码)/ /data(Docker 镜像)serverSQLite 存储目录
TODO_TOKEN_TTL24hserverJWT 有效期(Go time.Duration 格式)
TODO_CORS_ORIGINS空(不注入 CORS 中间件)server允许的 Origin allowlist,逗号分隔(精确匹配);特殊值 * 代表放行任意源(见 .env.example 注释)
TODO_GIN_MODEreleaseserverdebug / release / test
TODO_VERBOSEfalseserver打开更详细的请求日志(GORM info 级别)。合法取值:1/true/yes/on/t/y(true 集)或 0/false/no/off/f/n(false 集),大小写不敏感;非法值启动时直接报错退出config.go#parseBoolEnv

文档索引

💖 支持项目

如果这个项目对你有帮助,欢迎通过以下方式支持:

⭐ Star 项目

点击右上角的 ⭐ Star 按钮,让更多人发现这个项目。

💰 赞赏支持

赞赏码

License

MIT

Tag summary

Content type

Image

Digest

sha256:a1a4572b3

Size

13.7 MB

Last updated

4 months ago

docker pull hanxi/stickytodo