# 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 ,`) - 其他社区镜像(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 行,结构与字数基本持平,传播性增强