通过workbuddy对内容进行整改

This commit is contained in:
2026-08-16 18:20:33 +08:00
parent 62515589ae
commit 0d141eb8a7
2 changed files with 382 additions and 90 deletions
+127
View File
@@ -0,0 +1,127 @@
# 2026-08-16
## Obsidian Web 版部署教程改稿
**项目**:`E:\svn\OSQY\如何搭建web版本obsidian`
**用户需求**:检查初稿部署方案的可行性 + 搜同类竞品文章对照改稿,做成爆款向。
**关键发现**:
- 初稿 Caddyfile 里**硬编码了 4 段真实 API 凭证**(阿里云 AccessKey、DNSPod Token、Cloudflare Token),已经提示用户必须去对应云厂商轮换
- 部署方案 3 个硬伤:reverse_proxy 用了 `localhost:88`(caddy 容器内的 localhost 指向自己)、HTTPS 端口映射成 `8001:443`(公网 443 访问失败)、basic_auth 哈希硬编码(人人密码一样)
- 缺 WS_ORIGINS、缺离线安装(国内服务器首启下载 Obsidian 会被墙)、缺 Caddy 固定镜像来源说明
**已交付**:
- `如何搭建web版本obsidian.md` 重写完毕,347 行
- 新结构:痛点 → 竞品对比 → 准备清单 → 6 步部署 → 踩坑/进阶 → FAQ → 结尾引导
- 镜像:使用官方 `nobbe/ignis:latest` + `caddy:2`,清华/阿里云镜像用户可自行替换
- 加了 Tailscale 替代方案(无公网 IP 场景)
**参考的同类文章**:
- 喵斯基部落 moewah.com(结构最好,参考了它的标题钩子和 FAQ 形式)
- yanh.tech(简洁的 docker-compose 编排)
- 飞牛俱乐部 fnnas.com(早期社区帖)
- jinli.io(VNC 方案对比)
- 官方仓库:Nystik-gh/ignis
**下次可继续**:
- 用户处理 4 段密钥轮换后,回填一份自己验证过的截图
- 考虑加一张架构图(docker-compose 启动后的网络拓扑)
- 写 Obsidian Git 自动备份的下篇
## 二次改稿(同日 17:42)
**用户新要求**:1) 默认假定无 80 端口;2) 突出主题、删非必要内容、精简。
**改动**:
- 证书改为 **DNS 验证(acme_dns)为主方案**,Caddyfile 全局块直接内置;compose 只映射 `443:443`,去掉 80
- Caddy 官方 `caddy:2` 镜像不带 DNS 插件 → 增加 `Dockerfile.caddy`(xcaddy 编译 alidns/dnspod/cloudflare 三模块),compose 改 `build:`;Cloudflare 用户可选现成 `caddy-dns/cloudflare`
- 全文 347 → 约 130 行:砍掉 5 方案对比表(压缩成 2 句)、环境变量大表、10 条 FAQ 砍到 3 个核心坑(证书失败/离线安装/无公网 IP)
- 保留:WS_ORIGINS、离线 .deb 安装、Tailscale、备份/升级一行带过
**教训**:中国用户服务器常见无 80 端口(运营商封锁),DNS 验证是默认正确姿势;官方 caddy 镜像无 DNS provider 插件是必讲的前提,否则读者直接抄配置会失败。
## 三次改稿(同日 17:48)
**用户提出新问题**:电信家庭网下入站 443 是否也被封?
**结论**:是。国内家庭宽带默认封入站 80/443,多数用户还没公网 IP(CGNAT)。acme_dns 只能解决证书签发(出站),解决不了外部访问(入站)。
**改动(已交付)**:文章主线改为 **frp 内网穿透 + 轻量云服务器**:
- 云服务器(有公网 IP):`snowdreamtech/frps`,host 网络监听 7000 + 443,`frps.toml`(bindPort/auth.token)
- 家里:原 ignis + caddy(acme_dns 证书不变,TLS 终止在家里)+ 新增 `snowdreamtech/frpc` 服务(host 网络,`frpc.toml` 把本地 443 转发到云服务器 443)
- 架构:浏览器 → 云服务器 443 → frp 隧道 → 家里 Caddy 443 → ignis:8080;家里不需要公网 IP 和任何入站端口
- 备选保留:无云服务器 → 非标端口 8443(acme_dns 不变)或 Tailscale
- 坑新增:安全组放行 7000/443、token 不一致、云服务器 443 被占、家里 443 被占可改 8443
- 篇幅约 185 行
## 四次改稿(同日 17:54):用户假定没有云主机
**用户选择**:主线改为**非标端口 8443**(零成本、直连家里、数据不出网;前提:有公网 IP + 8443 未被运营商封)。
**改动(已交付)**:
- 删除 frps/frpc 全部内容(云服务器步骤整个移除)
- Caddy 端口映射 `443:443` → `8443:443`;WS_ORIGINS 域名带 `:8443`
- 新增第 1 步「验证前提」:ip.sb 对光猫 WAN 口 IP 判断有无公网 IP(100.64~100.127 为 CGNAT);在线端口扫描测 8443 是否被封
- 新增第 5 步 DDNS:`jeessy/ddns-go` 容器(host 网络,web 配置 :9876),飞牛用户可用内置 DDNS(阿里云/腾讯云/花生壳/DuckDNS)
- 新增第 6 步:光猫/路由器端口转发 8443
- 备选(文末):Cloudflare Tunnel(零成本、无需公网 IP、自动 HTTPS、数据过 CF、国内速度一般)、Tailscale(纯自用)
- 坑新增:8443 也被封可换 9443 等、换 IP 后连不上(DDNS 未生效)
**飞牛相关事实**(搜索确认):飞牛 fnOS 内置 Docker Compose 支持 + 镜像加速(docker.ketches.cn)+ FN Connect(官方穿透,限速,只适合管 fnOS 界面)+ 内置 DDNS(仅阿里云/腾讯云/花生壳/DuckDNS,无 DNSPod/CF)。ignis 镜像注意 x86/ARM 架构。
## 五次改稿(同日 18:00):端口 8443 → 666
**用户判断**:8443 属于常见端口、部分城市在封锁列表;666 冷门端口大概率不封。
**改动(已交付)**:全文所有 8443 替换为 666(标题、架构图、compose 映射 `666:443`、WS_ORIGINS 带 `:666`、端口转发、访问地址、坑/备选标题);被封端口列表恢复为 8080/8443/8888 并加说明"666 冷门端口大概率没事";备选端口 9443 → 6666;新增一条低端口提示(<1024,rootless Docker 需 `sysctl net.ipv4.ip_unprivileged_port_start=0`)。
## 六次改稿(同日 18:06):DDNS 并入 Caddy,删除 ddns-go
**用户需求**:DDNS 能否也用 Caddy 完成,简化部署步骤。
**查证结论**:`github.com/mholt/caddy-dynamicdns`(Caddy 作者 Matt Holt 写的 app 模块,2026-08 仍在活跃维护)可完全替代 ddns-go:
- xcaddy 加 `--with github.com/mholt/caddy-dynamicdns` 即可,复用文章已编译的 caddy-dns provider(alidns/dnspod/cloudflare)
- Caddyfile 全局块 `dynamic_dns { provider alidns {...} domains { example.cc ob } versions ipv4 ip_source simple_http https://api.ipify.org }`
- 默认 30 分钟查一次公网 IP,变化时更新 A 记录;dynamic_domains 可自动收集站点域名(本文用显式 domains 更稳)
- 注意:ACME 的 `acme_dns alidns` 是内建指令,与 dynamic_dns 用的 caddy-dns provider 是两套模块体系,Token 会写两遍(可改用 {env.XXX})
**改动(已交付)**:Dockerfile.caddy 加 dynamicdns 模块;compose 删 ddns-go 服务(3 容器→2 容器);Caddyfile 全局块加 dynamic_dns;删第 5 步"配置 DDNS",步骤重排为 6 步;常见坑改为查 `docker compose logs caddy | grep -i dynamic_dns`;Cloudflare 现成镜像提示改为"不含 dynamic_dns 模块"的警告。
## 七次改稿(同日 18:11):改用现成国内镜像 xm798/caddy:plus
**用户需求**:caddy-dynamicdns 有没有现成的国内镜像?
**查证结论**:
- 官方无预编译镜像(dynamic_dns 是 Non-standard 模块,官方只提供 xcaddy 自建)
- **`xm798/caddy:plus`**(国内作者,Docker Hub + 阿里云 `registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus`,README 官方推荐国内直拉):普通版含 alidns/dnspod/cloudflare/tencentcloud,plus 版再加 replace-response + **mholt/caddy-dynamicdns**
- **坑**:Caddy 2.10 后 libdns 升 1.0,dnspod 插件未适配,作者 2025-06 已从最新构建移除 dnspod → 用现成镜像时 DNSPod 不可用,需用腾讯云 tencentcloud 替代(`acme_dns tencentcloud <SecretId>,<SecretKey>`)
- 其他社区镜像(serfriz/caddy-*、vnxme/caddy)只含单 provider,且无国内镜像
**改动(已交付,用户选"现成镜像为主、自建作备选")**:
- compose 主线:`build:` → `image: registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus`
- 第 2 步 hash-password 镜像同步改为国内地址(原 `caddy:2` 国内也可能拉不动)
- Caddyfile 注释:DNSPod → 腾讯云(两处:acme_dns + dynamic_dns provider)
- 准备表格 DNS 服务商:阿里云/腾讯云/Cloudflare,DNSPod 用户指到文末自建备选
- 文末新增「备选:自建 Caddy」(原 Dockerfile.caddy + build: 回退写法 + DNSPod 语法 + `ENV GOPROXY=https://goproxy.cn,direct` 国内编译加速)
- 全文镜像拉取全部走国内地址
## 八次改稿(同日 18:14):ignis 也换国内镜像
**用户需求**:ignis 也改成国内镜像。
**查证**:本机 Docker 27.1.1 实测——Docker Hub 直连 000(连接失败,复现读者痛点);探测 6 个加速站对 `nobbe/ignis` 的 manifest 可用性:`docker.1panel.live` **200 且 tags 完整(0.8.0~0.8.9+latest)**;daocloud/1ms.run 401(无此镜像或需认证)、xuanyuan 429 限流、dockerpull.pw 000 不可达、rat.dev 302。
**改动(已交付)**:compose 里 `nobbe/ignis:latest` → `docker.1panel.live/nobbe/ignis:latest`(注释保留原版名);第 9 行项目说明同步;compose 提示区加一条"拉不动时换其他加速站前缀或配加速器后用原版名"。全文镜像现在全部国内直拉(caddy: registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus,ignis: docker.1panel.live/nobbe/ignis:latest)。
## 九次改稿(同日 18:17):面向网络传播的整体优化
**用户需求**:重新整理全文优化内容和标题,使文章更适合网络传播。
**改动(已交付)**:技术内容/命令/配置一字未动,重排结构与文案:
- 标题改为爆款向:「没有官方网页版?30 分钟自建一个 Web 版 Obsidian」+ 收益型副标题(免费/私有/带密码/不用买云服务器/封 80/443 不影响)
- 新增「先看痛点」:出差没带电脑/公司电脑不让装/平板随手记 三场景代入
- 新增「你能得到什么」表:时间 30 分钟、成本 0 元、2 容器、数据 100% 在家、前提不满足有备选
- 小标题全部口语化+承诺化:「开工前,备好这 5 样东西」「部署:6 步,30 分钟」「常见坑(先看这里,能省一小时)」「启动!看到登录页就成功了」
- 结尾改为「写在最后」:评论互动引导(卡住留言补坑)+ 点赞收藏转发 + 下篇预告强化
- 约 268 行,结构与字数基本持平,传播性增强
@@ -1,121 +1,286 @@
# 如何搭建web版本obsidian
# 没有官方网页版?30 分钟自建一个 Web 版 Obsidian
## 背景
> 免费、私有、带密码,数据全在自己家。不用买云服务器,运营商封了 80/443 也不影响——浏览器打开就能记笔记。
最近大神开源了一个 ignis 项目,可以通过网页访问 obsidian,但是默认是 http,且无密码,对于公网无法安全使用。
## 先看痛点:Obsidian 官方一直没做网页版
下面这个方案完善了安全访问,采用了加密的 https,并且有需要用户名登陆才能访问。
出差没带电脑、公司电脑不让装软件、想用平板随手记……Obsidian 重度用户绕不开这三件事。
## 具体步骤
官方没有网页版,官方同步要付费;过去想远程用 Obsidian,只能 VNC 远程桌面——又重又卡。
### 申请一个免费的域名,比如 ob.xxxx.cc
好在有 [Ignis](https://github.com/Nystik-gh/ignis):它在浏览器里重新实现了 Obsidian 依赖的 Electron API,让 Obsidian **原生跑在网页里**。vault 留在你自己家里,部署一次长期可用。
[搞一个免费 10 年的二级域名,公网访问飞牛 NAS](https://mp.weixin.qq.com/s?__biz=MzI2MTA5NzM5MA==&mid=2247499770&idx=1&sn=a5a1a3d78f3d729a45aa44204bb02694&scene=21&poc_token=HJpGeGqjYSRgiB6T6FdBh23s-6Fcjn90eBjF5E-6)
> 本文要用到的两个前提,先记住:
> - **Ignis 没内置认证**,必须自己套一层反向代理加密码(本文用 Caddy)
> - **必须 HTTPS**:剪贴板、离线缓存等 API 只在 HTTPS 下生效,纯 HTTP 公网访问会直接失效
### 通过反向代理 caddy,通过 https 访问 web 版本 obsidian
## 你能得到什么
1. 创建 4 个文件目录
| 项目 | 结果 |
|------|------|
| 时间 | 照做约 30 分钟 |
| 成本 | **0 元**,不需要云服务器 |
| 容器 | 2 个(ignis + Caddy),一个装好、一个转发 |
| 访问 | 任何设备的浏览器:`https://你的域名:666` |
| 数据 | **100% 留在家里**,不经过任何第三方 |
| 前提 | 家里有公网 IP + 666 未被运营商封(不满足也有免费备选,见文末) |
- vaults
- data
- obsidian-app
- caddy-data
2. 建立一个 caddyfile.txt 文件放到 caddy-data 目录
## 最大的坑:运营商封 80/443,但封不了 666
caddy 文件内容如下,注意:
国内电信/联通/移动家庭宽带默认封锁**入站 80、443**(防私搭网站),很多用户还没有公网 IP。
- ob.xxxx.cc 要改成自己的域名
- localhost 要改成自己服务器的 IP
- 默认用户名:Bob
- 默认密码:hiccup
但 **666 这种冷门端口大概率不在封锁名单**。本文的思路,就是把 HTTPS 挪到 666:
```yml
# 全局选项
{
# 全局使用alidns
acme_dns alidns {
access_key_id LTAI5tQfd6bBCHDR7HUjpWQR
access_key_secret b74sGYcTuwcvfiiQpTZtNWp5gCAQds
}
# 使用dnspod token
# acme_dns dnspod 37456,ejbe9tb5tiasjz2yu5u688vrwegpm
# 使用cloudflare api token
# acme_dns cloudflare v3ipam6idiwcmfub4iee4yjqyvykx
# 储存目录默认映射
storage file_system /data/cert
# 注意storage目录文件默认权限不允许其他人访问
# 如果需要被其他程序访问,可以自己手动chmod -R
# 关闭http自动重定向,可避免出现80端口占用问题(可手动加重定向配置)
auto_https disable_redirects
# 尝试申请Google CA
# 你需要到Google获取eab key来使用,详见:https://pki.goog/
# eab key仅仅是使用这个服务的权限与域名无关,不管是哪个账号申请,都是通用的
# 申请eab key不用会自动过期
# 如果你有Google domains,可以一键申请https://domains.google.com
# 注意:你需要自己解决https://dv.acme-v02.api.pki.goog/的科学访问
# email exmaple@gmail.com
# cert_issuer acme https://dv.acme-v02.api.pki.goog/directory {
# eab <EAB_密钥_ID> <EAB_HMAC_密钥>
# }
# 失败回退常规acme
# cert_issuer acme
# 屏幕打印日志,需要调试的时候可打开
# log {
# output stdout
# format console
# level debug
# }
}
ob.xxxx.cc {#这里要改成自己的域名
reverse_proxy http://localhost:88 #这里要改成自己服务器的IP
basic_auth {
# Username "Bob", password "hiccup"
Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
}
}
```text
浏览器 → https://ob.example.cc:666
→ 电信光猫/路由器(端口转发 666 → NAS)
→ 家里 NAS · Caddy(TLS 终止 + 密码)
→ ignis :8080
```
3. 使用以下 docker compose 文件建立 docker 服务
- 证书由 Caddy 用 **DNS 验证**申请和续期,走的是**出站**流量,运营商封不封入站端口都不影响
- 家里公网 IP 是动态的,用 **DDNS** 自动更新域名解析(Caddy 自带,不用额外容器)
- 数据完全留在家里,**不经过任何第三方**
```yml
version: '3'
**前提只有两个**:① 家里有公网 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 你的密码
```
记下输出的一长串 `$2a$14$...`,第 4 步要用。
### 3. 写 docker-compose.yml:只有 2 个容器
直接用现成镜像 **`xm798/caddy:plus`**——国内开发者维护,已内置阿里云 / 腾讯云 / Cloudflare 三个 DNS 模块和 dynamic_dns(DDNS)模块,同步在阿里云容器镜像仓库,**国内直拉、不用配加速器、不用编译**:
```yaml
services:
ignis:
image: registry.cn-hangzhou.aliyuncs.com/yue-images/ignis:latest
container_name: ignis2
caddy:
image: registry.cn-shanghai.aliyuncs.com/xm798/caddy:plus
container_name: caddy
restart: unless-stopped
ports:
- "88:8080"
- "666:443" # 公网走 666,映射到容器内 443
volumes:
- ./Caddyfile:/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
- WS_ORIGINS=https://ob.example.cc:666 # 改你的域名,注意带端口
volumes:
- ./vaults:/vaults
- ./data:/app/data
- ./obsidian-app:/app/obsidian-app
restart: unless-stopped
caddy:
pull_policy: always
image: registry.cn-hangzhou.aliyuncs.com/yue-images/caddy:latest
container_name: caddy
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- DNS=223.5.5.5,8.8.8.8
volumes:
- ./caddy_data:/data
ports:
# - '8000:80'
- '8001:443'
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:证书 + 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 {
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_source simple_http https://api.ipify.org
}
storage file_system /data/cert
auto_https disable_redirects
}
ob.example.cc {
encode gzip zstd
reverse_proxy ignis:8080
basic_auth {
admin $2a$14$你的密码哈希
}
}
```
> ⚠️ 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 步设置的密码:
![image](assets/image-20260809181306-0e1qd33.png)
登录后进入 Vault 管理器(`vaults/` 为空则新建):
![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 三件套自动备份方案——笔记双保险,一篇讲透。关注不迷路。