
之前一直在用 Obsidian 写笔记,Arch Linux 台式机、Windows 笔记本、iPhone、Android 手机全平台都要用。笔记同步用的是 Self-hosted LiveSync,但用久了有几个越来越受不了的问题——CouchDB 不透明,删除标记导致数据库膨胀,跨设备重建步骤多且容易出错。图床上也是散的,每张图片都存在本地 images/ 目录里,同步的时候图片也跟着传,仓库越来越大。
后来换了一套方案:同步用 fast-note-sync-service,图床用自建的 MinIO。用了一段时间,很稳,记录一下部署过程。
为什么是 fast-note-sync-service
最开始看到这个项目的时候其实没太在意,觉得 Obsidian 同步的轮子已经够多了。后来仔细看了一下,发现几个让我决定一试的点:
- 有 Web 管理页面——可以直接在浏览器里看同步状态、管理设备
- Token 认证——比 CouchDB 那套直观得多
- 分享功能——可以把笔记生成分享链接,还能设密码
- 同步历史——误删了能找回
- 自动备份——支持备份到 R2 等对象存储
- 更新非常勤快——作者几乎每周都有提交
于是就照着作者的文章部署了一套。
整体架构
一台 VPS 上跑了两个服务:
Caddy(统一入口)
├── example.com → fast-note-sync-service(笔记同步,端口 9000)
└── img.example.com → MinIO(图床,端口 9002)
域名放 Cloudflare,证书由 Caddy 自动申请。
部署 fast-note-sync-service(同步)
服务端部署参考了 fast-note-sync-service 项目。
服务端
VPS 上装 Docker 和 Docker Compose,然后创建项目目录:
# docker-compose.yml
version: "3"
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: your-root-password
MYSQL_DATABASE: fast_note_sync
volumes:
- ./mysql:/var/lib/mysql
restart: unless-stopped
redis:
image: redis:alpine
restart: unless-stopped
app:
image: ghcr.io/haierkeys/fast-note-sync-service:latest
ports:
- "9000:9000"
environment:
DB_HOST: mysql
DB_PORT: 3306
DB_DATABASE: fast_note_sync
DB_USERNAME: root
DB_PASSWORD: your-root-password
REDIS_HOST: redis
REDIS_PORT: 6379
depends_on:
- mysql
- redis
restart: unless-stopped
docker compose up -d
然后宿主机 Caddyfile 加一条反代:
example.com {
reverse_proxy localhost:9000
}
浏览器打开 https://example.com,注册管理员账号,进后台创建一个仓库(比如叫 obsidianmind),生成 API Token。
Obsidian 端
插件市场搜索 Fast Note Sync 安装:

在插件设置里填:
API 地址: https://example.com
API Token: 后台生成的 token
仓库名: obsidianmind
然后点手动同步,笔记就开始同步了。之后任何一端修改笔记,其他设备会自动同步,基本无感。
部署 MinIO 图床
同步解决了,但图片还是存在本地。仓库里散落着 2123 张图片、1.3GB,分布在几十个 images/、img/、assets/ 目录里。同步时这些图片也要跟着传,而且 Obsidian 文件列表里全是目录名,很难看。
于是决定在同台 VPS 上加一个图床。
docker-compose
version: '3'
services:
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
ports:
- "9002:9000" # API → 宿主机 9002
- "9003:9001" # 控制台
volumes:
- ./minio-data:/data
environment:
MINIO_ROOT_USER: obsidian
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD}
restart: unless-stopped
export MINIO_PASSWORD="your-password"
docker compose up -d
Caddyfile
宿主机 Caddyfile 最终是这样的:
example.com {
reverse_proxy localhost:9000 # 同步服务
}
img.example.com {
reverse_proxy localhost:9002 # 图床
}
MinIO 控制台
浏览器打开 http://VPS_IP:9003,用 obsidian + 刚才的密码登录。
- 创建 Bucket:
obsidian-img - 设置公开读:Bucket → Anonymous → 添加
s3:GetObject策略

Cloudflare DNS
类型: A
名称: img → VPS_IP(仅DNS)
这里不开启橙色云朵,因为 Caddy 自己管理 Let’s Encrypt 证书,开了 Cloudflare 代理会导致证书申请失败。
迁移旧图片
写了一个 Python 迁移脚本,用 boto3(S3 SDK)上传到 MinIO 并替换笔记中的引用。
pip install boto3 # 或 python -m venv .venv && .venv/bin/pip install boto3
python migrate.py

迁移结果:

然后清理本地图片目录:
# 根据自己的笔记目录结构调整
find . -type d \( -name images -o -name img -o -name image -o -name assets \) -not -path "./.obsidian/*" -exec rm -rf {} +
自动上传配置
旧图片迁移完后,新笔记的图片也需要自动上传到图床。装 Watermark Bucket Uploader 插件(这个插件支持 S3 协议且跨平台,iOS 也能用):
| 字段 | 值 |
|---|---|
| Access Key | obsidian |
| Secret Key | 你设的 MINIO_PASSWORD |
| Region | auto |
| S3 Bucket | obsidian-img |
| Custom Endpoint | https://img.example.com |
| Custom Image URL | https://img.example.com/obsidian-img/ |
| Force Path Style | 打开 |
| useCustomEndpoint | 打开 |
| useCustomImageUrl | 打开 |

配置好后,全平台 Obsidian 里粘贴图片都会自动上传到图床,笔记里插入的是 URL 而不是本地文件。
最终效果
现在这套方案跑起来是这样的:
- Arch / Windows / iOS / Android 写笔记 → Fast Note Sync 实时同步到其他设备
- 粘贴图片 → Watermark Bucket Uploader 自动上传 MinIO → 插入 URL
- 笔记只存文字+URL,同步飞快,仓库干净
- VPS 上既有同步服务又有图床,一台机器搞定
注意事项
- 端口冲突:宿主机 9000 跑着同步服务,MinIO 默认也是 9000。改映射到 9002 解决。
- Docker Caddy vs 宿主机 Caddy:一开始 docker-compose 里加了个 Caddy,和宿主机 80 端口冲突。去掉 Docker 里的 Caddy,全用宿主机 Caddy 统一代理。
- 插件开关没打开:Watermark Bucket Uploader 填了 Endpoint 和 Image URL 后,还要把对应的开关打开才生效。
- Custom Image URL 尾部斜杠:
https://img.example.com/obsidian-img/尾部要有/,否则粘贴的图片不显示。