首页
关于我们
友链链接
壁纸下载
更多
统计中心
热点搜索
图床上传
Search
1
[Win DD包] wes7-x86-cn-精简,安装后仅占用1.55G存储空间
25,500 阅读
2
保姆级教程!甲骨文ARM DD成Debian10并升级内核成5.10
6,197 阅读
3
N1教程:Openwrt安装docker webui界面(基于flippy openwrt n1固件)
5,228 阅读
4
ZFAKA小店Docker版之 数据的备份和迁移
5,052 阅读
5
甲骨文oracle ARM 重装 Debian 10
4,696 阅读
Linux学堂
网站建设
网络资源
主题插件
固件工具
主机评测
登录
Search
标签搜索
vps
typecho
linux
bench
mysql
cloudflare
nginx
lnmp
ssl
empirecms
openwrt
centos
google
docker
n1
301
qbittorrent
telegram
free
onedrive
V+变量
累计撰写
274
篇文章
累计收到
214
条评论
首页
栏目
Linux学堂
网站建设
网络资源
主题插件
固件工具
主机评测
页面
关于我们
友链链接
壁纸下载
统计中心
热点搜索
图床上传
搜索到
1
篇与
的结果
2025-04-03
笔记软件掌握在自己手中——使用docker自建e2ee开源笔记软件Notesnook服务器
一 前言笔记软件的类型非常多,划分的标准也不尽相同。以笔记的主要存储位置为标准,既有注重云端的 Notion, OneNote 和 FlowUs 等,也有本地优先的 Obsidian, Logseq 和思源笔记等;以编辑器类型为标准,既有专注于纯文本 / 富文本 / Markdown 编辑的,也有八面玲珑,兼顾日历、任务、书签管理功能的;以加密程度为标准,既有注重隐私安全的,也有注重便捷分享的。当一个笔记软件找到自己的定位,获得了一些目标人群的认可时,也往往会顾此失彼,让另一些潜在客户悄悄流失。例如,Obsidian 以强大的文本编辑能力、本地优先,无须网络或登录账户的快速便捷性和直接使用 .md 文档作为存储格式的开放性受到了用户的交口称赞,与此同时也因为同步的不便遭到了诟病;强调隐私保护的Standard Notes,因简洁的界面、开放源代码和经第三方审计的安全性在私人笔记市场受到欢迎,但与昂贵的订阅价格无法匹配的基础功能也令用户怨声载道。不论如何,这些赫赫有名的笔记软件都拥有自己的独门绝技。在这个硬件产品逐渐同质化的时代,软件产品的差异化,能让市场更加百花齐放,满足不同客户的需求。今天我们尝试部署的笔记软件 Notesnook 就是一个很好的例子。Notesnook 是由巴基斯坦的一个 3 人小公司 Streetwriters 开发的,在 2021 年发布了第一个版本,并在 2022 年以 GPL-3.0 许可证发布了服务端与客户端的源代码。同样以“端到端加密”的特性作为主打卖点,与拥有 8 年历史的 Standard Notes 相比,Notesnook 是一个年轻的竞争者。与 Standard Notes 较为稳健、保守的风格不同,Notesnook 广泛地听取用户意见,积极地引入各种新功能,而它比 Standard Notes 低许多的高级版定价以及相对慷慨的免费层服务吸引了不少 Standard Notes 的忠实用户。不少用户表示,“阻碍我转向 Notesnook 的唯一障碍就是不能自托管”。随着自托管进入 Alpha 阶段和服务端 Docker 镜像的发布,“不能自托管”的时代也已经结束了。尽管官方的完整版自托管文档尚未发布,但是已经有不少用户使用了 GitHub 仓库中的 Building From Source 或 成功进行了部署。docker compose我们使用 进行简便部署,并且用 Caddy 进行反代。docker compose二 安装教程1 前置条件1)Docker 和 Docker Compose2)4 个域名或者子域名,下面用 指代notes.example.io, mono.example.io, events.example.io, auth.example.io3)Caddy V22设置 compose.yml官方提供了一个开箱即用的 :docker-compose.ymlwget https://raw.githubusercontent.com/streetwriters/notesnook-sync-server/master/docker-compose.yml大部分内容我们都是不需要修改的:x-server-discovery: &server-discovery NOTESNOOK_SERVER_PORT: 5264 NOTESNOOK_SERVER_HOST: notesnook-server IDENTITY_SERVER_PORT: 8264 IDENTITY_SERVER_HOST: identity-server SSE_SERVER_PORT: 7264 SSE_SERVER_HOST: sse-server SELF_HOSTED: 1 IDENTITY_SERVER_URL: ${AUTH_SERVER_PUBLIC_URL} NOTESNOOK_APP_HOST: ${NOTESNOOK_APP_PUBLIC_URL} x-env-files: &env-files - .env services: validate: image: vandot/alpine-bash entrypoint: /bin/bash env_file: *env-files command: - -c - | # List of required environment variables required_vars=( "INSTANCE_NAME" "NOTESNOOK_API_SECRET" "DISABLE_SIGNUPS" "SMTP_USERNAME" "SMTP_PASSWORD" "SMTP_HOST" "SMTP_PORT" "AUTH_SERVER_PUBLIC_URL" "NOTESNOOK_APP_PUBLIC_URL" "MONOGRAPH_PUBLIC_URL" "ATTACHMENTS_SERVER_PUBLIC_URL" ) # Check each required environment variable for var in "$${required_vars[@]}"; do if [ -z "$${!var}" ]; then echo "Error: Required environment variable $$var is not set." exit 1 fi done echo "All required environment variables are set." # Ensure the validate service runs first restart: "no" notesnook-db: image: mongo:7.0.12 hostname: notesnook-db volumes: - dbdata:/data/db - dbdata:/data/configdb networks: - notesnook command: --replSet rs0 --bind_ip_all depends_on: validate: condition: service_completed_successfully healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh mongodb://localhost:27017 --quiet interval: 40s timeout: 30s retries: 3 start_period: 60s # the notesnook sync server requires transactions which only work # with a MongoDB replica set. # This job just runs `rs.initiate()` on our mongodb instance # upgrading it to a replica set. This is only required once but we running # it multiple times is no issue. initiate-rs0: image: mongo:7.0.12 networks: - notesnook depends_on: - notesnook-db entrypoint: /bin/sh command: - -c - | mongosh mongodb://notesnook-db:27017 <<EOF rs.initiate(); rs.status(); EOF notesnook-s3: image: minio/minio:RELEASE.2024-07-29T22-14-52Z ports: - 9000:9000 networks: - notesnook volumes: - s3data:/data/s3 environment: MINIO_BROWSER: "on" depends_on: validate: condition: service_completed_successfully env_file: *env-files command: server /data/s3 --console-address :9090 healthcheck: test: timeout 5s bash -c ':> /dev/tcp/127.0.0.1/9000' || exit 1 interval: 40s timeout: 30s retries: 3 start_period: 60s # There's no way to specify a default bucket in Minio so we have to # set it up ourselves. setup-s3: image: minio/mc:RELEASE.2024-07-26T13-08-44Z depends_on: - notesnook-s3 networks: - notesnook entrypoint: /bin/bash env_file: *env-files command: - -c - | until mc alias set minio http://notesnook-s3:9000 ${MINIO_ROOT_USER:-minioadmin} ${MINIO_ROOT_PASSWORD:-minioadmin}; do sleep 1; done; mc mb minio/attachments -p identity-server: image: streetwriters/identity:latest ports: - 8264:8264 networks: - notesnook env_file: *env-files depends_on: - notesnook-db healthcheck: test: wget --tries=1 -nv -q http://localhost:8264/health -O- || exit 1 interval: 40s timeout: 30s retries: 3 start_period: 60s environment: <<: *server-discovery MONGODB_CONNECTION_STRING: mongodb://notesnook-db:27017/identity?replSet=rs0 MONGODB_DATABASE_NAME: identity notesnook-server: image: streetwriters/notesnook-sync:latest ports: - 5264:5264 networks: - notesnook env_file: *env-files depends_on: - notesnook-s3 - setup-s3 - identity-server healthcheck: test: wget --tries=1 -nv -q http://localhost:5264/health -O- || exit 1 interval: 40s timeout: 30s retries: 3 start_period: 60s environment: <<: *server-discovery MONGODB_CONNECTION_STRING: mongodb://notesnook-db:27017/?replSet=rs0 MONGODB_DATABASE_NAME: notesnook S3_INTERNAL_SERVICE_URL: "http://notesnook-s3:9000" S3_INTERNAL_BUCKET_NAME: "attachments" S3_ACCESS_KEY_ID: "${MINIO_ROOT_USER:-minioadmin}" S3_ACCESS_KEY: "${MINIO_ROOT_PASSWORD:-minioadmin}" S3_SERVICE_URL: "${ATTACHMENTS_SERVER_PUBLIC_URL}" S3_REGION: "us-east-1" S3_BUCKET_NAME: "attachments" sse-server: image: streetwriters/sse:latest ports: - 7264:7264 env_file: *env-files depends_on: - identity-server - notesnook-server networks: - notesnook healthcheck: test: wget --tries=1 -nv -q http://localhost:7264/health -O- || exit 1 interval: 40s timeout: 30s retries: 3 start_period: 60s environment: <<: *server-discovery monograph-server: image: streetwriters/monograph:latest ports: - 6264:3000 env_file: *env-files depends_on: - notesnook-server networks: - notesnook healthcheck: test: wget --tries=1 -nv -q http://localhost:3000/api/health -O- || exit 1 interval: 40s timeout: 30s retries: 3 start_period: 60s environment: <<: *server-discovery API_HOST: http://notesnook-server:5264 PUBLIC_URL: ${MONOGRAPH_PUBLIC_URL} autoheal: image: willfarrell/autoheal:latest tty: true restart: always environment: - AUTOHEAL_INTERVAL=60 - AUTOHEAL_START_PERIOD=300 - AUTOHEAL_DEFAULT_STOP_TIMEOUT=10 depends_on: validate: condition: service_completed_successfully volumes: - /var/run/docker.sock:/var/run/docker.sock networks: notesnook: volumes: dbdata: s3data:在这个文件中,我们可以看到,Notesnook 服务器的必需组件包括:1)Vandot2)MongoDB 数据库3)S3 存储,这里采用了自建 MinIO 实例的方式(应该和 Ente 一样,不是必须使用 MinIO,可以接入外部 S3,不过我没试过,这里先不演示)4)身份验证服务器5)同步服务器6)SSE,用于提醒事件7)Monograph,用于分享笔记的公开链接(可以加密)。其中需要映射到的宿主机端口是 5264(同步服务器),6264(Monograph),7264(SSE)和 8264(身份服务器)。如果这些端口被占用,你可以选择映射到其他的端口。3设置 .env我们需要进行个性化设置的是 .env文件,官方同样提供了一个示例:.envINSTANCE_NAME=self-hosted-notesnook-instance # 改成你的实例名称 NOTESNOOK_API_SECRET= # 随机生成一串 >32 位的长字符串 DISABLE_SIGNUPS=false # 这个变量目前(2025年4月3日,v1.0-beta.1)还不能起效, # 如果你需要禁用注册功能,请在自己注册完之后添加以下变量: # DISABLE_ACCOUNT_CREATION=1 # SMTP 配置,用于接收 2FA 代码和重设密码,可以使用你自己的邮件提供商的 SMTP 配置 SMTP_USERNAME= # 大部分情况下,是你的邮箱用户名,例如
[email protected]
# 当 SMTP 用户名不是邮箱用户名的时候,会有 bug 出现, # Notesnook 会尝试把发件人地址(也就是邮件的 From) 设置为 SMTP 用户名,这在某些情况下会导致发件被拒绝。 # 我没有找到单独设置发件人地址的方法,已经提交 Issue SMTP_PASSWORD= # SMTP 密码,根据你的邮件提供商的指引设置 SMTP_HOST= # 例如 smtp.gmail.com SMTP_PORT= # SMTP 端口,例如 465 TWILIO_ACCOUNT_SID= # 不需要设置 TWILIO_AUTH_TOKEN= # 不需要设置 TWILIO_SERVICE_SID= # 不需要设置 NOTESNOOK_CORS_ORIGINS= # 不需要设置 NOTESNOOK_APP_PUBLIC_URL=https://app.notesnook.com # 换成你自己的 APP 域名,如 https://notes.example.io MONOGRAPH_PUBLIC_URL=http://localhost:6264 # 换成你的 Monograph 域名,如 https://mono.example.io AUTH_SERVER_PUBLIC_URL=http://localhost:8264 # 换成你的身份服务器域名 https://auth.example.io ATTACHMENTS_SERVER_PUBLIC_URL=http://localhost:9000 # MinIO 地址和端口,可以不用域名 MINIO_ROOT_USER= # 不需要设置 MINIO_ROOT_PASSWORD= # 不需要设置设置完直接启动即可:docker compose up -d4反向代理配置1)Nginx 和 Certbot 的配置参考这里:https://github.com/streetwriters/notesnook-sync-server/issues/20#issuecomment-2603896363server { listen 80; server_name auth.domain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name auth.domain.com; ssl_certificate /etc/letsencrypt/live/auth.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/auth.domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:8264; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } # Notes Server - With WebSocket server { listen 80; server_name notes.domain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name notes.domain.com; ssl_certificate /etc/letsencrypt/live/notes.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/notes.domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:5264; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 3600; proxy_send_timeout 3600; } } # Events Server - With WebSocket server { listen 80; server_name events.domain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name events.domain.com; ssl_certificate /etc/letsencrypt/live/events.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/events.domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:7264; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 3600; proxy_send_timeout 3600; } } # Monograph Server - With Cache server { listen 80; server_name mono.domain.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name mono.domain.com; ssl_certificate /etc/letsencrypt/live/mono.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mono.domain.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { proxy_pass http://localhost:6264; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_cache_valid 200 60m; add_header X-Cache-Status $upstream_cache_status; expires 1h; add_header Cache-Control "public, no-transform"; } }2)Caddy 的配置参考这里:https://github.com/streetwriters/notesnook-sync-server/issues/20#issuecomment-2763248500notes.example.io { reverse_proxy localhost:5264 } mono.example.io { reverse_proxy localhost:6264 } events.example.io { reverse_proxy localhost:7264 } auth.example.io { reverse_proxy localhost:8264 }正常情况下访问 能看到 Monograph 的默认页面就成功了。https://mono.example.io5在 Notesnook 客户端自定义服务器1)下载 Notesnook 的客户端,进入 Settings -> Servers,填写以下端点:同步服务器 URL:https://notes.example.io身份验证服务器 URL:https://auth.example.io事件服务器 URL:https://events.example.io专论服务器 URL:https:mono.example.io2)然后就可以输入你的邮箱注册账户了~需要注意的是,与 Vikunja 和 Vaultwarden 不同,Notesnook 的邮件验证不是可选项,所以需要填写可以接收到邮件的地址。如果需要关闭注册,可以在自己注册完后修改.env ,加入 DISABLE_ACCOUNT_CREATION=1。
2025年04月03日
19 阅读
0 评论
0 点赞