一款支持加密的笔记StandardNotes

什么是 Standard Notes ?

Standard Notes 是一款免费、开源且完全加密的笔记应用程序,支持端到端加密,拥有强大的扩展程序、编辑器和主题,客户端跨平台,支持包括:Linux,MacOS,Windows,Android,iOS 和 Web 网页。

Standard Notes 最大的特点是没有人可以解密您的笔记,但是这种安全级别的缺点就是:如果您忘记密码,则会丢失笔记,因为无法恢复、重置忘记的密码。

笔记是永久免费的,除非您想要使用其强大的扩展程序、编辑器和主题,不过没关系,既然是开源的,我们可以自己动手来丰衣足食。

如果您不想自己安装,可以直接使用官方的免费服务,地址:
https://app.standardnotes.org/

前期准备

  1. 支持 Docker 的群晖主机(黑白无所谓);
  2. 拥有有效 SSL 证书的域名;

下表是老苏准备的:

应用 局域网IP+端口 对应域名
服务端 192.168.0.197:3050 https://api.laosu.ml
WEB端 192.168.0.197:3001 https://app.laosu.ml

规划好之后可以先做反向代理,也可以在安装的过程中再设置

服务端安装

Standard Notes 采用了微服务架构,按照官方的教程,服务端安装完成后会有 7 个容器

官方教程:https://docs.standardnotes.org/self-hosting/docker/

7个容器

如果您跟老苏一样,采用了自定义数据库的话,安装完成后会有 6 个容器

自定义数据库6个容器

对比两张图,您应该会发现少的那个是 MySQL 容器

创建数据库

这一步是可选的,按官方的教程 MySQL 数据库是部署在容器里的,但老苏不建议这么干,原因有兴趣的可以自己度娘。

以往老苏都是用的 MariaDB 5 ,但是这次终于踩了坑,容器 standalone_syncing-server-js_1 的日志中会出现类似👇下面的错误

1
ERROR 1067 (42000): Invalid default value for 'created_at'

查阅了很多文档发现是 MariaDB 5.5 的问题,所以老苏不得不又安装了 MariaDB 10

通过 phpMyAdminMariaDB 10 中新建用户 standardnote,创建同名的库 standardnote 并授予所有权限。

安装 git

  • 套件中心设置 –> 套件来源 –> 新增

名称:随意,位置:http://packages.synocommunity.com/

  • 套件中心 –> 社群,找到并安装套件 Git

下载代码

用 SSH 客户端连到群晖,在 docker 目录中执行下面的命令

1
2
3
4
5
# 下载代码
git clone --single-branch --branch main https://github.com/standardnotes/standalone.git

# 进入目录
cd standalone

生成配置文件

1
2
# 初始化设置
./server.sh setup

编辑 .env 文件

这里可以修改 EXPOSED_PORT,默认端口为 3000,找一个不冲突的端口就可以,老苏随便改了个 3050

如果你准备和老苏一样使用自定义数据库,那跟数据库想关的部分也需要进行修改

  • DB_HOST:默认为 db,改为群晖(数据库主机)的 IP
  • DB_REPLICA_HOST:默认为 db,也改为群晖的 IP
  • DB_PORT:默认为 3306,但一般来说同时安装了 MariaDB 5MariaDB 10 的话,MariaDB 10 端口是 3307
  • DB_USERNAME:默认为 std_notes_user,改为我们第一步创建的 standardnote
  • DB_PASSWORD:默认为 changeme123,改为我们第一步创建的密码
  • DB_DATABASE:默认为 standard_notes_db,改为我们第一步创建的 standardnote

生成秘钥

1
2
# 生成秘钥,每次运行会产生不同的32位十六进制的值
openssl rand -hex 32

有 2 个文件 4 个环境变量值需要用到随机秘钥,这是出于安全性的考虑

  • 根目录下的 .env 文件中 AUTH_JWT_SECRET,默认值为 auth_jwt_secret
  • docker 目录下的 auth.env 文件中的
    • JWT_SECRET 默认值为 secret
    • LEGACY_JWT_SECRET 默认值为 legacy_jwt_secret
    • ENCRYPTION_SERVER_KEY 默认值为 feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308,这个值必须要32位,前面3个没有这个要求

如果你只是搭着玩玩,不改也可以,如果是要放到公网使用,那最好别图省事。

编辑 docker-compose.yml

如果你不打算用自定义数据库,这一步可以跳过,否则需删除db 相关部分

动手修改前记得备份、备份、备份

一、删除每个微服务 depends_on: 后面的 - db,大概有4处

二、将 entrypoint:[] 中的 db 改为群晖 IP,大概也是4处

改完之后

三、删除 db 节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
db:
image: mysql:5.6
environment:
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
ports:
- 3306
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8 --collation-server=utf8_general_ci
volumes:
- ./data/mysql:/var/lib/mysql
- ./data/import:/docker-entrypoint-initdb.d
networks:
- standardnotes_standalone

创建目录

data 目录新建两个子目录,mysqlredis

如果是自定义数据库,只要建一个 redis 就可以

启动服务

1
2
# 首次运行可能需要一段时间
./server.sh start

从脚本看,实际上就是执行了 docker-compose up -d

而从 docker-compose.yml 看,除了 MySQLRedis 外,由于Standard Notes 采用了微服务架构,分为了 authapi-gatewaysyncing-server-js 多个服务

如果中途报类似这样的错误

一般都是网络问题,只要再次执行就可以了,反正老苏前前后后执行了 4 次才把镜像都下载成功,看到👇下图这样的就是已经成功了

按官方指导启动

使用自定义数据库启动

1
2
# 查看日志
./server.sh logs

只有看到 api-gateway_1 | {"message":"Server started on port 3000","level":"info"}

才表示服务已经启动成功。你也可以通过查询状态来看是否启动成功

1
2
# 查询状态
./server.sh status

如果所有的服务状态都是 up就可以了

还有更简单的办法,访问 http://群晖IP:3050/healthcheck,如果你看到 OK,也表示服务都启动了

不用浏览器也是可以的

1
2
# 查询页面状态
curl http://localhost:3050/healthcheck

如果你修改了配置文件,可以用下面的命令重启服务

1
2
# 先停止再启动
./server.sh stop && ./server.sh start

设置反向代理

到这里,服务端就安装完成了。

客户端安装

先设置反向代理,因为后面环境文件 .env 中会用到

web 客户端

standalone 新建子目录 web

1
2
3
4
5
6
7
8
# 建子目录
mkdir web

# 进入目录
cd web

# 新建 .env 文件
vi .env

将下面的内容粘贴进去,:wq 保存退出

来自于官方的样例文件,地址:https://github.com/standardnotes/web/blob/develop/.env.sample

  • SF_DEFAULT_SERVER 默认为 http://localhost:3000,为服务端地址,改用相应的域名 https://api.laosu.ml,如果你用的 http 协议,那么不管是注册还是登陆,都会卡死在 generating register keys或者 generating login keys
  • APP_HOST 默认为 http://localhost:3001,为 WEB 客户端的地址,改用相应的域名 https://app.laosu.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
RAILS_ENV=development
PORT=3001
WEB_CONCURRENCY=0
RAILS_LOG_TO_STDOUT=true
# Log Level options: "INFO" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL"
RAILS_LOG_LEVEL=INFO
RAILS_SERVE_STATIC_FILES=true
SECRET_KEY_BASE=test
APP_HOST=https://app.laosu.ml

EXTENSIONS_MANAGER_LOCATION=extensions/extensions-manager/dist/index.html
SF_DEFAULT_SERVER=https://api.laosu.ml

# Development options
DEV_DEFAULT_SYNC_SERVER=https://api.standardnotes.com
DEV_EXTENSIONS_MANAGER_LOCATION=public/extensions/extensions-manager/dist/index.html
ENABLE_UNFINISHED_FEATURES=false
DEV_WEBSOCKET_URL=wss://sockets-dev.standardnotes.com

# NewRelic (Optional)
NEW_RELIC_ENABLED=false
NEW_RELIC_THREAD_PROFILER_ENABLED=false
NEW_RELIC_LICENSE_KEY=
NEW_RELIC_APP_NAME=Web
NEW_RELIC_BROWSER_MONITORING_AUTO_INSTRUMENT=false

接下来就可以启动 Web 端容器了

1
2
# 启动容器
docker run -d -p 3001:3001 --name standardnotes_web --env-file=.env standardnotes/web:stable

在浏览器中打开 http://群晖IP:3001 就能看到主界面了

首先要注册用户

如果注册有问题,打开 Advanced Option,确认一下服务器地址是否正确,如果不正确可以重新输入正确的地址
密码千万不能忘记了,因为 Standard Notes 用密码来加密笔记

接下来就可以开始使用了,虽然是英文,但是挺简单的

PC客户端

PC 客户端是基于 Electron 开发的,所以和 WEB客户端 有着相同的界面,只要在 Advanced Option 中输入服务器地址即可使用。

移动端没试,大家有兴趣可以自己试试。

小结

至于扩展程序之类的,暂时没精力去搞,不过老苏找到了一篇文章 Standard Notes - Docker self-hosted alternative for all your note needs,地址已经放在参考文档中,写的非常详细,有兴趣的可以自己研究一下。

总的来说,在群晖里跑还是觉得有点臃肿了,只是尝尝鲜还是可以的。

参考文档

Standard Notes
地址:https://github.com/standardnotes

Standard Notes | A Simple And Private Notes App
地址:https://standardnotes.com/

Self-hosting with Docker | Standard Notes Documentation
地址:https://docs.standardnotes.org/self-hosting/docker/

Standard Notes - Docker self-hosted alternative for all your note needs
地址:https://www.blackvoid.club/standard-notes-docker-self-hosted-alternative/