Files
OSQY/如何搭建web版本obsidian/如何搭建web版本obsidian.md
2026-08-25 14:43:22 +08:00

295 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 没有官方网页版?30 分钟自建一个 Web 版 Obsidian
> 免费、私有、带密码,数据全在自己家。不用买云服务器,运营商封了 80/443 也不影响——浏览器打开就能记笔记。
![Snipaste_2026-08-09_18-27-29](assets/Snipaste_2026-08-09_18-27-29-20260809183007-aavwkz2.png)
## 先看痛点:Obsidian 官方一直没做网页版
出差没带电脑、公司电脑不让装软件、想用平板随手记……Obsidian 重度用户绕不开这三件事。
官方没有网页版,官方同步要付费;过去想远程用 Obsidian,只能 VNC 远程桌面——又重又卡。
好在有 [Ignis](https://github.com/Nystik-gh/ignis):它在浏览器里重新实现了 Obsidian 依赖的 Electron API,让 Obsidian **原生跑在网页里**。vault 留在你自己家里,部署一次长期可用。
> 本文要用到的两个前提,先记住:
> - **Ignis 没内置认证**,必须自己套一层反向代理加密码(本文用 Caddy)
> - **必须 HTTPS**:剪贴板、离线缓存等 API 只在 HTTPS 下生效,纯 HTTP 公网访问会直接失效
## 你能得到什么
| 项目 | 结果 |
|------|------|
| 时间 | 照做约 30 分钟 |
| 成本 | **0 元**,不需要云服务器 |
| 容器 | 2 个(ignis + Caddy),一个装好、一个转发 |
| 访问 | 任何设备的浏览器:`https://你的域名:666` |
| 数据 | **100% 留在家里**,不经过任何第三方 |
| 前提 | 家里有公网 IP + 666 未被运营商封(不满足也有免费备选,见文末) |
## 最大的坑:运营商封 80/443,但封不了 666
国内电信/联通/移动家庭宽带默认封锁**入站 80、443**(防私搭网站),很多用户还没有公网 IP。
但 **666 这种冷门端口大概率不在封锁名单**。本文的思路,就是把 HTTPS 挪到 666:
```text
浏览器 → https://ob.example.cc:666
→ 电信光猫/路由器(端口转发 666 → NAS)
→ 家里 NAS · Caddy(TLS 终止 + 密码)
→ ignis :8080
```
- 证书由 Caddy 用 **DNS 验证**申请和续期,走的是**出站**流量,运营商封不封入站端口都不影响
- 家里公网 IP 是动态的,用 **DDNS** 自动更新域名解析(Caddy 自带,不用额外容器)
- 数据完全留在家里,**不经过任何第三方**
**前提只有两个**:① 家里有公网 IP;② 666 没被运营商封。不满足?直接跳到文末备选,还有两条免费的路。
## 开工前,备好这 5 样东西
| 需要 | 说明 |
|------|------|
| 家里有公网 IP | 打电信客服 10000 申请(部分地区直接有,客服一般会给);拿不到就跳到最后备选 |
| 一个二级域名 | 如 `ob.example.cc`,解析由 DDNS 自动维护,不用手动改 |
| DNS 服务商 API Token | 阿里云 / 腾讯云 / Cloudflare 都行,**只开"修改 DNS"权限**(签证书、更新解析都用它);必须用 DNSPod 的见文末自建备选 |
| 路由器端口转发 | 把公网 666 转发到家里 NAS 的 666(光猫是路由模式就在光猫上做) |
| 一台能跑 Docker 的机器 | NAS / 旧电脑 / 小主机,1 GB 内存即可 |
## 部署:6 步,30 分钟
### 1. 花两分钟确认:公网 IP 有没有?666 封没封?
- **公网 IP**:浏览器打开 `ip.sb` 记下 IP;登录光猫(`192.168.1.1`)看 WAN 口 IP。两者一致 = 有;WAN 口是 `100.64.x.x ~ 100.127.x.x` = CGNAT 大内网,**没有**,直接看文末备选
- **666 封没封**:用在线端口扫描工具(如 `ping.chinaz.com` 的端口检测),输入公网 IP 和 666,显示"开放"即可。部分城市 8080/8443/8888 这类常见端口都在封锁名单,666 这种冷门端口大概率没事,但务必先测
### 2. 生成登录密码
basic_auth 要求 bcrypt 哈希,别照抄网上的,自己生成:
```bash
docker run --rm registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus caddy hash-password --plaintext 你的密码
```
不会用命令的可以用在线网站生成:https://bcrypt-generator.com/
![alt text](assets/image.png)
记下输出的一长串 `$2a$12$gYYzSsTk7UMh5BFiBScMUO/uO0vn3ab0JiU8uHcU6e/V/riPCAHBu`,第 4 步要用。
### 3. 写 docker-compose.yml:只有 2 个容器
直接用现成镜像 **`xm798/caddy:plus`**——国内开发者维护,已内置阿里云 / 腾讯云 / Cloudflare 三个 DNS 模块和 dynamic_dns(DDNS)模块,同步在阿里云容器镜像仓库,**国内直拉、不用配加速器、不用编译**:
```yaml
services:
caddy:
image: registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus
container_name: caddy
restart: unless-stopped
ports:
- "666:443" # 公网走 666,映射到容器内 443
volumes:
- ./caddyfile.txt:/etc/caddy/Caddyfile:ro
- ./caddy_data:/data
- ./caddy_config:/config
networks:
- ignis-net
ignis:
image: docker.1panel.live/nobbe/ignis:latest # Docker Hub 原版:nobbe/ignis:latest
container_name: ignis
restart: unless-stopped
environment:
- OBSIDIAN_VERSION=1.12.7
- PUID=1000
- PGID=1000
volumes:
- ./vaults:/vaults
- ./data:/app/data
networks:
- ignis-net
networks:
ignis-net:
```
> 注意:这个镜像**不含** DNSPod 模块(Caddy 2.10 后 libdns 升级,dnspod 插件尚未适配,作者已从最新构建移除)。必须用 DNSPod 的读者,见文末「自建 Caddy(备选)」。
>
> ignis 走 1Panel 加速站前缀(国内直拉,已验证可用);哪天拉不动了,换成其他加速站前缀,或配好 Docker 加速器后用原版 `nobbe/ignis:latest`,其他配置不用动。
家里建 `~/obsidian-web`,把上面存为 `docker-compose.yml`。几个要点:
- caddy 和 ignis 同在 `ignis-net` 内网,Caddy 用服务名 `ignis:8080` 访问上游
- ignis **不映射任何端口**,公网只能通过 Caddy 进入
- 证书走 DNS 验证,**不依赖任何入站端口**;666 只是暴露在公网的入口
- **DDNS 也由 Caddy 承担**,所以整个部署只有 2 个容器
- 666 < 1024 是低端口,常规 Docker(root 守护进程)可直接绑定;用 rootless Docker 的读者需先执行 `sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0`
### 4. 写 caddyfile.txt:证书 + DDNS + 密码,一次配好
把域名、密码哈希、DNS Token 换成你自己的:
```caddyfile
# 全局配置:用 DNS 验证申请证书(出站申请,不依赖任何入站端口)
{
acme_dns alidns {
access_key_id <你的阿里云 AccessKey ID>
access_key_secret <你的阿里云 AccessKey Secret>
}
# 用腾讯云 DNS 的话,替换上面为:
# acme_dns tencentcloud <SecretId>,<SecretKey>
# 用 Cloudflare 的话,替换上面为:
# acme_dns cloudflare <API Token>
# DDNS:家里公网 IP 变了,自动更新 ob.example.cc 的解析
# Token 与上面 acme_dns 用同一个;不想写两遍可改用 {env.XXX} 环境变量
dynamic_dns {
# 使用阿里云 DNS 作为更新 provider
provider alidns {
access_key_id <你的阿里云 AccessKey ID>
access_key_secret <你的阿里云 AccessKey Secret>
}
# 用腾讯云 DNS 的话,替换上面为:
# provider tencentcloud <SecretId>,<SecretKey>
# 用 Cloudflare 的话,替换上面为:
# provider cloudflare <API Token>
domains {
example.cc ob
}
versions ipv4
# 获取公网 IP 的方式,可以使用多个作为备份
ip_source simple_http https://myip.ipip.net
ip_source simple_http https://ip.3322.net
}
storage file_system /data/cert
auto_https disable_redirects
}
ob.example.cc {
encode gzip zstd
reverse_proxy ignis:8080
basic_auth {
# Username "admin", password "qingyuan"
admin $2a$12$gYYzSsTk7UMh5BFiBScMUO/uO0vn3ab0JiU8uHcU6e/V/riPCAHBu
}
}
```
> ⚠️ Token 用**最小权限**子账号或专用 Token(只给"修改 DNS 记录"权限),**永远不要把主账号凭证写进配置**。
配好之后 DDNS 也一并生效:Caddy 每 30 分钟查一次家里公网 IP,变了就自动更新 `ob.example.cc` 的 A 记录,不需要任何额外容器。
> 飞牛用户更习惯图形界面的话,也可以用系统内置的「网络 → DDNS」(支持阿里云 / 腾讯云 / 花生壳 / DuckDNS),二选一即可。
### 5. 路由器端口转发
把公网 `666` 转发到家里 NAS 的 `666`。电信光猫默认是路由模式:登录光猫(`192.168.1.1`)→ 端口映射 / 虚拟服务器 → 新增:外部端口 666 → 内网 NAS IP 的 666(TCP)。光猫改过桥接、用自备路由器的,就在路由器上做同样的映射。
### 6. 启动!看到登录页就成功了
```bash
docker compose up -d
docker compose logs -f ignis
# 首次启动会从 Obsidian 官方源下载客户端,看到 Listening on http://0.0.0.0:8080 即成功
```
浏览器打开 **`https://ob.example.cc:666`**,输入用户名(示例 `admin`)和第 2 步设置的密码:qingyuan
![image](assets/image-20260809181306-0e1qd33.png)
登录后进入 Vault 管理器(`vaults/` 为空则新建):
![alt text](assets/image-1.png)
![Snipaste_2026-08-09_18-27-29](assets/Snipaste_2026-08-09_18-27-29-20260809183007-aavwkz2.png)
到这里,**Web 版 Obsidian 就跑起来了**——没花一分钱,数据全在自己家,任何设备的浏览器都能用。
## 常见坑(先看这里,能省一小时)
**证书申请失败**
- `docker compose logs caddy` 看报错
- 确认域名解析已指向**家里公网 IP**(`dig ob.example.cc`)——刚配完 DDNS 可能有延迟,等一两分钟
- 确认 Token 权限是"修改 DNS 记录"且对应域名所在的账号
- Cloudflare 用户要把代理(橙色云)关掉,保持 DNS only
**666 也是封的 / 没有公网 IP**
- 换文末备选方案(Cloudflare Tunnel / Tailscale)
- 有些城市 8080、8443、8888 这类常见端口都在封锁名单,部署前先测;666 被真封了,换一个没封的端口(如 6666)改 compose 映射和 DDNS 域名即可
**换 IP 后连不上**
- 看 Caddy 日志里 dynamic_dns 的输出:`docker compose logs caddy | grep -i dynamic_dns`,确认解析已更新(再 `nslookup ob.example.cc` 核对)
- 光猫/路由器重启会换 IP,IP 检测默认 30 分钟一次,稍等几分钟
**国内服务器下载不了 Obsidian**
首次启动要从 GitHub 下载客户端,被墙会卡在 `curl: (18) ...`。手动下载 `.deb` 包挂载进去:
```bash
# 在有外网的机器下载,再传到 ~/obsidian-web/
wget https://github.com/obsidianmd/obsidian-releases/releases/download/1.12.7/obsidian_1.12.7_amd64.deb
```
`docker-compose.yml` 的 ignis 服务加两行:
```yaml
volumes:
- ./obsidian.deb:/packages/obsidian.deb:ro
environment:
- OBSIDIAN_PACKAGE=/packages/obsidian.deb
```
然后 `docker compose up -d` 重启。
**日常备份 / 升级**
- 备份:vault 就是普通文件夹,直接 `tar czf vault-$(date +%F).tar.gz vaults/`,或同步到 Git / WebDAV
- 升级:`docker compose pull && docker compose up -d`,笔记和配置都不会动
## 备选:没有公网 IP,或 666 也被封
- **Cloudflare Tunnel**:零成本、无需公网 IP、自动 HTTPS、标准域名不带端口。家里跑 cloudflared 容器,主动出站连 Cloudflare 边缘即可,连端口转发都省了。缺点:国内免费版速度一般、数据会经过 Cloudflare。适合域名已托管在 CF 的读者
- **Tailscale**:纯自用最省事。服务器和设备的 Tailscale 登录同一账号、开 MagicDNS,服务器执行 `tailscale serve --bg 8080`,浏览器访问生成的 `https://xxx.ts.net` 即可,同样有 HTTPS。缺点:只有装了 Tailscale 的设备能访问
## 备选:自建 Caddy(必须用 DNSPod / 想自定义模块时)
主线镜像不支持 DNSPod,且属于第三方构建。必须用 DNSPod、或想自己加模块的读者,改用 xcaddy 自建,模块、配置与主线完全一致。新建 `Dockerfile.caddy`:
```dockerfile
FROM caddy:2-builder AS builder
RUN xcaddy build --with github.com/caddy-dns/alidns \
--with github.com/caddy-dns/dnspod \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-dynamicdns
FROM caddy:2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
```
compose 里把 caddy 的 `image:` 一行换成:
```yaml
build:
context: .
dockerfile: Dockerfile.caddy
```
Caddyfile 的 DNS provider 相应改回 DNSPod 语法:`acme_dns dnspod <ID>,<Token>`、`provider dnspod <ID>,<Token>`。
> 国内编译慢/失败的话:先给 Docker 配好镜像加速(拉 `caddy:2-builder`),再在 Dockerfile 顶部加一行 `ENV GOPROXY=https://goproxy.cn,direct`,让 xcaddy 从国内 Go 代理拉模块,编译时间能从十几分钟降到一两分钟。
---
## 写在最后
这篇教程踩过的坑,基本都写进去了:运营商封锁、国内拉不动镜像、证书失败、首次启动卡下载……如果你照着做,卡在文章里没有的地方,欢迎评论区留言,我会把新坑补进来。
觉得有用的话,点个**赞**、**收藏**,转给同样在折腾 Obsidian 的朋友。
**下一篇预告**:Obsidian + Ignis + Obsidian Git 三件套自动备份方案——笔记双保险,一篇讲透。关注不迷路。