一个简洁美观的笔记应用,支持 H5 和 Web 端,自适应设计,支持明暗主题切换。
macOS / Linux:
./start.sh
Windows:
start.bat
脚本会自动:
启动成功后:
你这次要求的「Go 后端托管/内嵌 SvelteKit 静态文件」对应如下脚本:
./dev-kit.sh
打开 http://localhost:9001(SvelteKit dev),API 走代理到 http://localhost:9000。
./start-prod.sh
启动后直接打开 http://localhost:9000。
说明:
sqlite_fts5 build tag(用于 SQLite FTS5)backend/public/,并由 Go 在运行时托管(SPA fallback 到 index.html)目标:别人可以 docker run 或 docker compose up 在 NAS/服务器上自部署,并且数据可持久化。
必填环境变量:
MEMO_JWT_SECRET**:JWT 密钥(生产必须设置,建议 32+ 字符)推荐环境变量:
MEMO_ADMIN_PASSWORD**:用于初始化/重置管理员 admin 的密码(不设置则首次启动会随机生成并打印到容器日志)MEMO_CORS_ORIGINS**:允许的前端域名(逗号分隔),例如 https://your.domain,https://nas.local容器数据目录:
/data/notes.db**:SQLite 数据库(通过 MEMO_DB_PATH 指定)/data/storage**:附件目录(通过 MEMO_STORAGE_DIR 指定)示例:
docker run -d \
--name memo-studio \
-p 9000:9000 \
-v memo_data:/data \
-e MEMO_JWT_SECRET="please-change-me" \
-e MEMO_ADMIN_PASSWORD="your-strong-password" \
-e MEMO_ENV=production \
-e GIN_MODE=release \
memo-studio:local
启动后访问:http://localhost:9000
默认管理员用户名:admin
直接使用仓库根目录的 docker-compose.yml:
docker compose up -d --build
admin/admin123MEMO_ADMIN_PASSWORD:启动时会确保 admin 存在并重置密码,同时标记“需要修改密码”PORT**:监听端口(默认 9000)MEMO_DB_PATH**:SQLite 路径(默认 ./notes.db;容器建议 /data/notes.db)MEMO_STORAGE_DIR**:附件目录(默认 ./storage;容器建议 /data/storage)MEMO_CORS_ORIGINS**:CORS 白名单(逗号分隔;不填默认放开)MEMO_JWT_SECRET**:JWT 密钥(生产必须设置)建议发布 linux/amd64 与 linux/arm64 两种架构镜像(群晖/威联通/树莓派常用)。
后续可以用 GitHub Actions + buildx 自动构建并推送到 Docker Hub/GHCR。
本仓库已内置 GitHub Actions:推送 tag(如 v0.1.0)会自动构建并推送镜像到 GHCR:
ghcr.io/<你的GitHub用户名>/<仓库名>:latestghcr.io/<你的GitHub用户名>/<仓库名>:v0.1.0git tag v0.1.0
git push origin v0.1.0
Actions 运行完成后,别人即可部署:
docker run -d \
--name memo-studio \
-p 9000:9000 \
-v memo_data:/data \
-e MEMO_JWT_SECRET="please-change-me" \
-e MEMO_ADMIN_PASSWORD="your-strong-password" \
ghcr.io/<你的GitHub用户名>/<仓库名>:latest
很多 NAS 更习惯从 Docker Hub 拉取镜像。本仓库工作流已支持在打 tag 时同步推送 Docker Hub,前提是你配置好 Secrets:
在 GitHub 仓库 Settings → Secrets and variables → Actions 添加:
DOCKERHUB_USERNAME**:你的 Docker Hub 用户名DOCKERHUB_TOKEN**:Docker Hub Access Token(建议用 token,不要用密码)发布后 Docker Hub 镜像名规则:
docker.io/<DOCKERHUB_USERNAME>/<仓库名>:latestdocker.io/<DOCKERHUB_USERNAME>/<仓库名>:v0.1.0别人部署示例:
docker run -d \
--name memo-studio \
-p 9000:9000 \
-v memo_data:/data \
-e MEMO_JWT_SECRET="please-change-me" \
-e MEMO_ADMIN_PASSWORD="your-strong-password" \
docker.io/<你的DockerHub用户名>/<仓库名>:latest
本仓库已内置工作流:.github/workflows/ai-pr-review.yml
默认不会对所有 PR 自动评论(避免刷屏/与 Gemini 等机器人冲突)。运行方式如下:
ai-review**,工作流就会自动运行并更新同一条评论AI PR Review 工作流,并填写 pr_number工作流会:
在 GitHub 仓库:Settings → Secrets and variables → Actions → New repository secret 添加:
AI_REVIEW_API_KEY**:模型 API Key(必填)AI_REVIEW_MODEL**:模型名(必填,例如 gpt-4o-mini / gpt-4.1-mini / 你自建模型名)AI_REVIEW_BASE_URL**:可选,OpenAI 兼容接口地址(默认 https://api.openai.com/v1)说明:
AI_REVIEW_API_KEY/AI_REVIEW_MODEL,工作流会自动跳过(不报错)cd backend
go mod download
go run main.go
后端服务将在 http://localhost:9000 启动
cd frontend
npm install
npm run dev
前端应用将在 http://localhost:9001 启动
memo-studio/
├── backend/ # Go 后端服务
│ ├── main.go # 入口文件
│ ├── database/ # 数据库相关
│ ├── models/ # 数据模型
│ ├── handlers/ # API 处理器
│ ├── middleware/ # 中间件
│ └── utils/ # 工具函数
├── frontend/ # Svelte 前端应用
│ ├── src/
│ │ ├── components/ # 组件
│ │ ├── stores/ # 状态管理
│ │ └── utils/ # 工具函数
│ └── vite.config.js
├── start.sh # 一键启动脚本
└── README.md
GET /health - 健康检查端点POST /api/auth/login - 用户登录{ "username": "string", "password": "string" }{ "token": "string", "user": {...} }POST /api/auth/register - 用户注册{ "username": "string", "password": "string", "email": "string" }{ "token": "string", "user": {...} }GET /api/auth/me - 获取当前用户信息{ "id": number, "username": "string", "email": "string", "created_at": "datetime" }GET /api/notes - 获取所有笔记[{ "id": number, "title": "string", "content": "string", "tags": [...], "created_at": "datetime", "updated_at": "datetime" }]GET /api/notes/:id - 获取单个笔记{ "id": number, "title": "string", "content": "string", "tags": [...], "created_at": "datetime", "updated_at": "datetime" }POST /api/notes - 创建笔记{ "title": "string", "content": "string", "tags": ["string"] }PUT /api/notes/:id - 更新笔记{ "title": "string", "content": "string", "tags": ["string"] }DELETE /api/notes/:id - 删除笔记{ "success": true, "message": "笔记已删除" }DELETE /api/notes/batch - 批量删除笔记{ "ids": [number] }{ "success": true, "deleted": number, "message": "string" }GET /api/tags - 获取所有标签[{ "id": number, "name": "string", "color": "string", "created_at": "datetime" }]PUT /api/tags/:id - 更新标签{ "name": "string", "color": "string" }DELETE /api/tags/:id - 删除标签{ "success": true, "message": "标签已删除" }POST /api/tags/merge - 合并标签{ "sourceId": number, "targetId": number }{ "success": true, "message": "标签合并成功" }使用 SQLite 数据库,首次运行会自动创建数据库文件 backend/notes.db 和表结构。
数据库表结构:
users - 用户表notes - 笔记表tags - 标签表note_tags - 笔记标签关联表前端使用 Vite,默认支持热模块替换(HMR):
使用方式:
frontend/src/ 下的任何文件后端 Go 服务默认不支持热重载,有两种方式:
方式一:使用 Air(推荐,自动热重载)
安装 Air:
go install github.com/cosmtrek/air@latest
在 backend 目录运行:
cd backend
./start-dev.sh
# 或直接运行
air
修改 Go 代码后,Air 会自动重新编译和重启服务
方式二:手动重启(简单但需要手动操作)
修改代码后,需要手动停止并重新启动后端服务:
# 停止服务(Ctrl+C)
# 然后重新运行
cd backend
go run main.go
backend.log - 后端服务日志frontend.log - 前端开发服务器日志macOS / Linux:
在运行 ./start.sh 的终端中按 Ctrl+C 即可停止所有服务。
Windows:
关闭运行 start.bat 的命令窗口即可停止所有服务。
如果 9000 或 9001 端口被占用,启动脚本会自动尝试清理。如果失败,请手动停止占用端口的进程:
# 查看端口占用
lsof -i :9000
lsof -i :9001
# 停止进程(替换 PID)
kill -9 <PID>
Go 依赖:
cd backend
go mod download
go mod tidy
npm 依赖:
cd frontend
rm -rf node_modules package-lock.json
npm install
如果数据库文件损坏,可以删除后重新启动:
cd backend
rm notes.db
# 重新启动服务,数据库会自动创建
前端:
后端:
go install github.com/cosmtrek/air@latest.air.toml 配置文件是否存在MIT License