资讯动态

Typora+Git+云服务器:打造跨设备无缝同步的Markdown笔记方案

发布时间:2026/10/15 12:12:21 来源:尧图企业网站定制
平时写技术文档最烦的就是不同设备之间的同步问题。白天在公司台式机上码了一下午笔记回家打开笔记本发现最新内容还躺在公司那台机器里。U盘来回拷忘过一次就长记性了。用聊天工具发给自己一不小心发错群就是事故。我后来搭了一套 Typora GitHub 云服务器 的组合方案本地用 Typora 所见即所得地写 MarkdownGit 负责版本管理云服务器当中转仓库GitHub 做归档备份。整套链路从手动敲命令到全自动同步跑了一年多没出过大问题。这篇就把完整的搭建思路、配置过程和踩过的坑都写出来想给笔记做多端同步的人可以直接照着抄。这套方案本质上解决的痛点有三个一是写作体验Typora 的即时渲染写起来舒服二是版本历史每次改动都有记录改错了能随时回滚三是多端访问在公司写、回家接着写中间不需要任何手工搬运。它适合的人群也很明确写技术笔记、维护项目文档、积累博客素材的人只要你日常产出是 Markdown 格式这套东西就能用。1. 方案选型为什么是这三个组件拼在一起很多人第一反应是“直接用云笔记不就行了吗费这个劲干嘛”。确实市面上的云笔记产品很多功能也齐全但我个人对笔记工具的要求比较偏执——第一数据必须掌握在自己手里纯文本格式、不锁死在某个生态里第二要有真正的版本历史不是只给我一个“历史版本”按钮而是每次改动都能看 diff第三写作时不能被编辑器绑架今天用这个编辑器写明天想换另一个工具也能继续编辑。这三个诉求叠加起来Markdown Git 几乎是唯一解。Typora 负责生产内容它把 Markdown 渲染成类似 Word 的阅读体验但文件本质是纯文本。Git 负责记录每一次文件的变动无论删除、修改还是新增都有迹可循。云服务器和 GitHub 负责让内容在不同设备之间流动起来本地写完推送到服务器服务器再归档到代码托管平台。1.1 三个角色是怎么分工的各组件在链路里的位置是这样的Typora本地写作工具负责把想法落地成 Markdown 文档设置好图片目录之后插图和附件也能一并管理。Git版本控制核心每次写完一段内容就提交一次相当于给文档拍快照留下可追溯的变更记录。云服务器中转站所有设备的 Git 远程仓库都指向它内容推送不需要依赖第三方平台内网访问或者走公网都行。代码托管平台你用的 GitHub归档备份。云服务器上的钩子脚本会自动把变更推送上去相当于异地多了一份副本。为什么要绕这么一圈因为我希望本地的每一次 push 都尽可能顺畅。如果所有设备直接连 GitHub不同网络环境下访问体验差异很大时好时坏碰上一次推送失败你得反复重试。而云服务器在公网有个固定入口从本地连过去基本不会有这种问题。GitHub 在这里的角色是“归档位”由服务器去跟它打交道本地设备就不必关心这个过程了。1.2 对比了一圈为什么不用现成的云笔记有对比才有说服力。我把自己曾经用过的几个方案都摆出来对比过方案数据所有权版本历史编辑器自由度离线可用云笔记类产品平台方持有通常不开放完整历史被编辑器绑定有限网盘同步盘自己持有冲突覆盖风险大任意本地编辑器可以自建 NAS自己持有依赖内置套件一般可以Markdown Git 服务器自己持有完整且可 diff任意本地编辑器完全网盘同步盘的问题在于文件冲突。一个文件在两台设备上改了不一样的内容同步盘经常搞出“冲突副本”命名乱七八糟得手工合并。Git 的处理方式是提交历史同样的场景只是多了一个分支节点拉下来 rebase 一下就能解决不会凭空多出几个副本文件。自建 NAS 其实是最理想的方案但成本偏高一台像样的入门级 NAS 硬件加上硬盘前期投入不小还需要内网穿透才能在公网访问。相比之下一台入门级云服务器年费便宜得多资源占用还低——因为文档仓库的体积很小Git 仓库基本不消耗 CPU 和内存1核2G 的配置绰绰有余这点账算下来云服务器是性价比最高的选择。2. 动手第一步本地仓库与编辑器的准备整套链路的第一步不是在服务器上搞什么高深配置而是先在本地把 Git 仓库和 Typora 的环境理顺。很多人上来就搭服务器、配钩子结果本地还没 init后面全是白搭。2.1 本地 Git 初始化与首次提交新建一个文档目录我习惯把笔记按年份或者按项目分子目录比如docs/2025/、docs/projects/。然后在这个目录下执行mkdir my-notes cd my-notes git init git add . git commit -m init notes这里有个细节Git 默认分支名是master现在大家普遍用main如果你希望从一开始就用main可以执行git branch -M main。这不是必须的但后面写脚本和钩子的时候分支名统一会省很多事。首次提交完成之后本地仓库就算是建起来了。这个时候你用什么编辑器都可以打开这个目录开始写但如果用 Typora我还建议做两件事——打开自动保存配置图片路径。Typora 的自动保存在偏好设置里可以打开默认会把未保存的修改在一段时间内自动写盘。对 Git 工作流来说自动保存的意义在于内容不断被写入文件而每当你觉得一个阶段写完了手动提交一次Git 就把这个时刻的内容完整记录了下来。两件事配合既不担心丢内容又有清晰的时间线节点。2.2 Typora 的偏好设置与图片路径图片和附件的处理是很多人在 Markdown 文档管理里忽略的地方。默认情况下Typora 插入一张图片引用的是本机绝对路径比如C:\Users\xxx\Pictures\xxx.png这种文件只有你这台机器能看推到远程仓库别人打不开换个设备同样打不开。我的习惯是在 Typora 的偏好设置里把“插入图片时”的行为设为“复制到 ./assets 目录”同时勾选“优先使用相对路径”。这样每篇文章旁边会自动生成一个assets文件夹图片和文档放在一起路径是相对的![架构图](./assets/architecture.png)相对路径的另一个好处是以后如果你想把 Markdown 发布成静态博客文档和图片只要整体拷贝过去图片引用不会断。这个习惯我从一开始就养成了后来发布文档到博客站点的时候完全没踩过图片丢失的坑。本地内容准备得差不多之后开始安排远程仓库。这里要分清两个远程概念一个是你自己的云服务器一个是你用的代码托管平台。两个角色不同配置方式也不同。3. 云服务器中转仓库的搭建与接入标题里既然提到了腾讯云我就直接用腾讯云轻量应用服务器来举例。选服务器的时候不用太纠结配置文档仓库的 Git 操作基本上只占磁盘写入和网络带宽CPU 几乎不吃选基础款就行。操作系统我用的 DebianUbuntu 也完全一样下面命令在两种系统上都能直接跑。3.1 为什么要自建一个中转仓库先说清楚中转仓库到底是干嘛的。假设没有这个中转站你的多台设备都直接把代码托管平台当远程仓库每次 push 和 pull 都在跟外部平台打交道。实际用下来不同网络环境下连接外部平台的顺畅程度不太一样有的设备可能始终连接失败遇到一次 push 超时你就得停下来处理网络问题写作思路全打断了。自建中转仓库的意义在于本地设备只跟自己的服务器通信路径短、可控性强。推送成不成功、快不快这些因素掌握在你自己手里。至于服务器跟 GitHub 之间的通信那是服务器自己的网络环境不需要本地设备关心。整个数据链路是这样的本地设备Typora Git ↓ push 云服务器中转仓库裸仓库 ↓ 钩子自动触发 云服务器归档工作区 ↓ push GitHub 远程仓库异地归档3.2 在服务器上创建裸仓库并用 SSH 接入登录服务器创建一个专用的 Git 用户这样仓库权限跟其他服务隔离安全性更好adduser git mkdir /home/git/notes.git git init --bare /home/git/notes.git chown -R git:git /home/git/notes.git--bare参数很多人第一次见会疑惑解释一下裸仓库没有工作区只保存 Git 的版本对象和索引信息它就是一个纯中转站不允许在上面直接改文件。普通仓库会保留一份可编辑的工作文件裸仓库不要这份文件因为没有人会在服务器上直接编辑文档多一份文件只会增加混乱。本地生成 SSH 密钥如果没有的话ssh-keygen -t ed25519 -C notes-sync cat ~/.ssh/id_ed25519.pub把输出的公钥内容追加到服务器的/home/git/.ssh/authorized_keys文件里mkdir /home/git/.ssh echo ssh-ed25519 AAAA... your-key-comment /home/git/.ssh/authorized_keys chown -R git:git /home/git/.ssh chmod 700 /home/git/.ssh chmod 600 /home/git/.ssh/authorized_keys本地这边把远程仓库地址改成服务器git remote add origin gityour-server-ip:/home/git/notes.git git push -u origin main第一次 push 的时候 SSH 会提示确认服务器指纹输入 yes 回车即可。之后每次推送都不需要输入密码因为走的是密钥认证。这也是我没用 HTTPS 方式连接服务器仓库的原因——HTTPS 每次都要输账号密码虽然可以用凭据管理器记住但远不如密钥来得清爽。到这里本地到中转仓库的链路已经通了。下面给服务器加上 GitHub 归档的能力。3.3 通过钩子把变更自动归档到 GitHub先在 GitHub 上建一个空的私有仓库比如叫notes-repo不要勾选初始化 README保持干净。然后服务器上需要有一个能访问这个仓库的 SSH 密钥# 在服务器上执行如果还没生成过先生成 sudo su - git ssh-keygen -t ed25519 -C server-archive cat /home/git/.ssh/id_ed25519.pub把输出的公钥添加到 GitHub 账户的 SSH keys 里。它是服务器访问 GitHub 的凭证。GitHub 仓库建好之后接下来是最关键的一步给中转裸仓库写一个 post-receive 钩子。这个钩子在每次收到 push 之后自动执行把新内容拉到服务器上的一个工作区再推送到 GitHub# 在服务器上执行 cd /home/git/notes.git/hooks vim post-receive写入以下内容#!/bin/bash export GIT_WORK_TREE/home/git/notes-backup export GIT_DIR/home/git/notes-backup/.git # 先拉取最新内容 git pull origin main # 再推送到 GitHub git push github main然后创建钩子里需要用到的工作区cd /home/git git clone /home/git/notes.git notes-backup cd notes-backup git remote add github gitgithub.com:your-name/notes-repo.git git remote set-head origin -d chmod x /home/git/notes.git/hooks/post-receive这里有个容易踩的坑git pull origin main拉取裸仓库的引用时需要先确保本地分支和远端分支的对应关系是对的。如果 clone 出来的是master分支而裸仓库里是main就会拉错。建议 clone 完之后直接执行git checkout -b main origin/main把本地默认分支也切到 main。后面推送就不会出现分支不匹配的问题了。这套钩子跑通的效果是本地只要git push origin main服务器收到内容之后自动更新备份工作区然后自动推到 GitHub。你的本地设备全程只跟自己的服务器通信GitHub 那边发生什么完全不感知。4. 把同步从手动变成半自动、全自动落到日常使用最影响体验的就是同步的便捷程度。如果每次写完都手动敲三条命令时间一长就会偷懒一偷懒内容就不同步了。所以我把同步做成了半自动并且在部分场景下做到了全自动。4.1 一个通用的一键同步脚本脚本的思路很简单把git add、git commit、git push三步合并成一个命令给每次提交自动打上时间戳。这样你在任何目录下执行一次脚本当前的改动就全部推到服务器并归档到 GitHub。Mac 和 Linux 下我用这样的脚本#!/bin/bash cd $(dirname $0) || exit 1 git add -A if git diff --cached --quiet; then echo 没有需要提交的变更 exit 0 fi git commit -m docs: sync $(date %Y-%m-%d %H:%M:%S) git push origin mainWindows 下对应的.bat版本echo off cd /d %~dp0 git add -A git diff --cached --quit if %errorlevel% equ 0 ( echo no changes exit /b 0 ) git commit -m docs: sync %date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,8% git push origin mainWindows 用户注意%date%和%time%的输出格式跟系统区域设置有关不同电脑年月日的排列顺序可能不一样提交信息里显示成什么格式都不影响 Git 使用但如果你在意提交日志的整洁性可以手动调整一下格式。脚本建好之后给它加执行权限然后做个软链接到/usr/local/bin/notes-sync这样你在任何地方打开终端输入notes-sync都能同步不用记住脚本放在哪个目录。这个习惯帮我保持了一年多的日更同步几乎没有漏过。4.2 利用文件监听做全自动同步半自动已经很省事了但还不够——有时候我在 Typora 里写一段话切到终端执行脚本回来继续写这个流程切来切去还是有点打断思路。于是我在 Linux 环境下用文件监听把同步做成了全自动。引入了一个小工具叫inotifywaitDebian 系用apt install inotify-tools安装。它的作用是监控目录里的文件变动一旦有写入、新建、删除事件就触发我指定的命令。我写过这样一个监听循环while inotifywait -r -e modify,create,delete --exclude .git /home/your-user/my-notes; do cd /home/your-user/my-notes git add -A git commit -m auto sync $(date %Y-%m-%d %H:%M:%S) || true git push origin main done把这段脚本放到后台运行比如用nohup或者直接注册成 systemd 服务之后我在 Typora 里每次按下保存监听器都会察觉到变化自动完成提交和推送。这个过程通常在一两秒内完成感知不到延迟。但这里我要说一个负责任的补充全自动同步不适合所有人。如果你习惯了在文档里写一半就保存、第二天接着改全自动会把半成品也提交进历史里。虽然 Git 有历史记录可以回滚但这种操作多了历史时间线就变得很脏回滚时反而不好定位。我的建议是日常内容用半自动脚本只有写博客草稿这种“想好了再写”的内容才用全自动监听。或者折中一下把自动提交的信息统一带上WIP前缀后期整理时一眼就能认出来哪些是草稿。4.3 移动端怎么办顺手提一下移动端。Typora 没有手机版所以这套方案在手机上不能直接“写”但我用了一个可行的策略手机上只读。GitHub 的网页端可以直接浏览私有仓库里的 Markdown 文件渲染效果不错。偶尔在外面想查一个文档打开手机浏览器进 GitHub 仓库页面就能看。这种方式牺牲了编辑能力换来了零成本访问。对大部分场景来说“能查资料”就够了真正需要写长文的时候还是回电脑前操作。如果你确实需要在手机上改文档也可以用手机端的 Git 客户端配合同一套仓库或者用支持 Markdown 的其他编辑器但说实话手机小屏打字的体验本身就不好我不太建议为了这点便利把整个方案复杂化。5. 多设备实操中的那些坑这套链路跑久了各种问题也遇了不少。每次新设备接入、网络波动、多人协作其实是自己在两台设备上同时写都暴露过一些之前没注意到的细节。下面这些事我建议你在开始之前就做好心理准备。5.1 push 被拒、提交冲突怎么办最常遇到的情况是你在家用台式机写了内容并推送了第二天到公司笔记本上的仓库还停留在昨天的状态你直接在旧的快照上写了新内容提交后 push 被拒——因为远端已经有新的提交了。遇到这个报错别慌这不是内容丢了只是 Git 在保护历史不被覆盖。正确的操作是先把远端内容拉下来合并再重新推送git pull --rebase origin main git push origin main--rebase参数和默认的merge行为有个区别rebase 会把你的本地提交“接到”远端最新提交的后面历史线是一条直线而 merge 会生成一个合并节点历史线会出现分叉。个人文档仓库建议全程 rebase历史干净。如果有冲突Git 会标出冲突文件用 Typora 打开能看到类似 HEAD的分隔符手动保留正确的版本删掉分隔符再执行git add . git rebase --continue git push origin main在日常使用中我自己基本没有遇到像样的冲突因为文档内容大多数情况下是一台设备改一个文件真正冲突的场景太少了。只要你记得换设备后第一件事是git pull绝大概率不会走到冲突那一步。5.2 图片、附件与大文件的处理细节用 Git 管理文档最大的边界就是“大文件”和“二进制文件”。Git 的设计目标是文本它对文本文件能给出精确到每一行的差异对比但对二进制文件只能判断“变没变”没法告诉你具体哪里变了。所以图片、PDF、视频这类文件一旦频繁变动仓库体积会迅速膨胀。我的处理策略是文档配图用相对路径放进assets目录体积控制在几 MB 以内这些推上去完全没有问题。超过 20 MB 的附件或者像设计稿、安装包这类文件不放进 Git 仓库本地移动端需要时单独传输。图片目录还有一个细节Typora 默认图片复制会重命名比如image-20250407-142030.png这种带时间戳的名字。好处是不会重名坏处是文件多了以后assets目录里全是这种无意义命名的文件后期清理很麻烦。我在 Typora 偏好设置里关掉了自动重命名改用自己在文档目录下建一个images文件夹手动归档。这一步纯粹是个人偏好看你自己对整洁度的容忍程度。5.3 新设备上三分钟恢复全部文档这套方案的另一个优势体现在换设备、重装系统的时候。我经历过一次硬盘故障系统盘全没了当时只焦虑了两分钟因为文档都同步在远端。新机器上只需要三个步骤# 安装 Typora 和 Git # 生成 SSH 密钥把公钥加到服务器和 GitHub 上 git clone gityour-server-ip:/home/git/notes.git my-notes克隆下来之后文档结构和历史记录全在。Typora 的偏好设置需要重新配一下图片路径、主题、导出模板等但这些一次配置花不了几分钟。相比以前用网盘同步时那种“文件夹还在但里面文件同步到一半”的尴尬状态这个方案在恢复数据这件事上让人特别安心。要注意的是克隆下来的仓库默认只有远端的分支状态本地分支需要一条命令指定git checkout -b main origin/main否则后续提交会提交到master上两边分支对不上push 的时候又会出现分支不匹配的报错。这个问题我第一次换电脑时遇到过当时还以为是服务器配置有问题排查了半天。5.4 服务器和 GitHub 的关系容易混淆很多人看到这套方案会问为什么有了自己的服务器还要再接入 GitHub两头都同步不是多此一举吗这个问题我解释过很多次。把服务器当唯一远程仓库的风险在于如果服务器磁盘故障、数据丢了你的文档就没有任何备份了。GitHub 在这里承担的是异地容灾的角色相当于给自己的资料多买了一份保险。服务器到 GitHub 的推送由钩子触发不需要人工干预所以这个备份过程对你完全透明。日常使用中你只需要关心本地到服务器的 push 是否成功GitHub 那一侧有没有同步好通过网页端刷新看一下就心里有数了。6. 日常维护与扩展方向这套方案不是搭完就一劳永逸的长期跑下来有几个维护点值得你留意。一是服务器的磁盘空间Git 仓库虽然体积小但如果长期把附件也往里面塞空间迟早会告急建议每个月看一眼磁盘占用。二是备份策略GitHub 是外部备份但如果你愿意还可以在服务器上写一个定时任务定期把仓库打成一个压缩包存到对象存储多一层保险。6.1 定时任务的配置参考在服务器上配置一个 crontab 任务每周凌晨把存档目录压缩并打上日期标记0 3 * * 0 tar -czf /home/git/backup/notes-$(date \%Y\%m\%d).tar.gz /home/git/notes-backup这个功能不是必须的但如果你管理的是特别重要的文档多一个离线压缩包总是让人更踏实。压缩包本身很小一个积累了数年的文档仓库通常也就几十 MB存多久都不是负担。6.2 把文档发布成个人博客最后聊一个扩展方向。GitHub 仓库可以开启 Pages 服务把 Markdown 文档渲染成静态网页等于这份笔记顺便变成了一个个人博客。你可以利用 GitHub 的 Actions 功能提交之后自动触发构建效果基本等同于一个零成本托管站点。对有写作分享需求的人而言这套文档管理方案的终点不只是“同步”而是一个可以对外展示的内容平台。我个人目前的用法是每天在本地写笔记半自动同步到服务器和 GitHub偶尔把其中一些整理成文章单独建仓库发布出来。整个过程行云流水没有一次因为“找不到内容”“版本不对”这些问题浪费过时间。这套方案我越用越满意的一点是它把所有环节都控制在了自己手里。写作工具可以换换任何支持 Markdown 的编辑器都不影响仓库托管平台可以换仓库换一个远程地址就行服务器也可以换重新配置一下密钥和钩子半小时搬完。数据本身永远是纯文本格式永远有版本历史永远有多个副本。这种掌控感是用现成云笔记产品体会不到的。如果你也经常在多台设备间切换写文档强烈建议照着这套思路搭一遍成本不高但省下来的心力是实打实的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑