Gitee Pages迁移与Jekyll博客重生(从零到一实战)

📅 2026/6/20 8:18:18
Gitee Pages迁移与Jekyll博客重生(从零到一实战)
1. 为什么需要迁移Gitee Pages博客去年开始不少开发者发现Gitee Pages服务变得不太稳定。我自己的Beautiful Jekyll主题博客就经常遇到访问异常的情况。经过排查发现主要问题出在几个方面首先是访问速度明显下降。由于Gitee Pages的CDN节点调整部分地区用户访问时延高达3-5秒这对博客体验影响很大。其次是资源加载问题很多引用的CSS/JS文件经常加载失败。最严重的是Gitee Pages服务已经明确表示将逐步停止对个人用户的免费支持。我测试过几个替代方案GitHub Pages访问速度尚可但国内偶尔抽风Vercel速度优秀但有使用限制Netlify功能全面但配置复杂本地部署完全可控但需要服务器成本经过对比我最终选择了GitHub Pages作为主要迁移目标。虽然GitHub在国内访问不算完美但配合CDN加速后实测90%的地区都能在2秒内完成页面加载。更重要的是GitHub Pages的服务稳定性已经经受了多年考验。2. 迁移前的准备工作2.1 完整备份原博客在开始迁移前务必备份所有重要数据。我建议采用以下备份策略代码仓库克隆git clone https://gitee.com/yourname/yourrepo.git cd yourrepo git remote add backup /path/to/backup_folder git push backup --all数据库导出如果有mysqldump -u username -p blog_db blog_backup.sql静态资源打包tar -czvf assets.tar.gz ./images ./uploads我遇到过最惨痛的教训是没备份评论数据。当时使用了Gitalk插件迁移时直接覆盖了仓库导致所有历史评论丢失。现在我的备份流程一定会包含代码仓库完整克隆数据库定时导出用户上传资源打包第三方服务配置截图2.2 检查依赖项兼容性不同平台对Jekyll插件的支持程度不同。迁移前需要重点检查主题兼容性bundle exec jekyll doctor插件白名单GitHub Pages支持的插件列表https://pages.github.com/versions/自定义域名配置# CNAME文件内容 yourblog.com我使用的Beautiful Jekyll主题就遇到了插件冲突问题。原主题依赖的jekyll-paginate插件在GitHub Pages上需要特定版本花了我半天时间调试。建议提前在本地环境测试构建JEKYLL_ENVproduction bundle exec jekyll build3. 分步迁移到GitHub Pages3.1 创建GitHub仓库GitHub Pages要求仓库必须命名为username.github.io。操作步骤新建仓库gh repo create username.github.io --public --clone转移代码cd username.github.io cp -r ../old-gitee-blog/* . git add . git commit -m 迁移博客初始版本推送到GitHubgit push -u origin main这里有个小技巧GitHub默认分支现在是main而Gitee常用master。我建议统一使用main分支避免构建失败。可以通过以下命令修改git branch -m master main git push -u origin main3.2 配置GitHub Pages在仓库Settings中找到Pages选项选择部署分支通常是main指定构建目录默认是/root启用自定义域名如果需要我第一次迁移时犯了个错误没有启用GitHub Actions。导致每次推送后需要手动触发构建。正确的做法是在仓库设置中开启自动构建# .github/workflows/pages.yml name: Build and Deploy on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv2 - uses: actions/jekyll-build-pagesv13.3 处理资源路径问题Gitee和GitHub的Pages服务URL结构不同需要修改所有资源引用修改_config.yml中的baseurlbaseurl: # GitHub Pages不需要子路径检查所有图片链接![图片](/assets/image.jpg) → ![图片](assets/image.jpg)更新绝对路径的CSS/JS引用link href/css/style.css → link hrefcss/style.css我写了个Python脚本自动处理这些路径问题import os import re for root, dirs, files in os.walk(.): for file in files: if file.endswith((.md, .html)): path os.path.join(root, file) with open(path, r) as f: content f.read() content re.sub(r\(/, (, content) f.seek(0) f.write(content)4. 迁移后的优化策略4.1 加速国内访问GitHub Pages在国内访问速度参差不齐。我测试了几种优化方案CDN加速推荐CloudflareCNAME记录 → username.github.io静态资源托管图片上传到图床如SM.MSJS/CSS托管在CDN如BootCDN开启HTTP/2和Brotli压缩# Nginx配置示例 server { listen 443 http2; gzip on; brotli on; }实测下来使用CDN后首屏加载时间从4.2秒降到了1.3秒。这张表格对比了不同方案的性能优化方案首屏时间TTFB费用原生GitHub4.2s320ms免费Cloudflare CDN1.3s89ms免费Vercel代理1.1s65ms付费套餐4.2 实现自动部署我建立了完整的CI/CD流程本地写作后自动构建alias pubgit add . git commit -m update git push使用GitHub Actions自动部署# .github/workflows/deploy.yml name: Deploy on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv2 - run: bundle install - run: bundle exec jekyll build - uses: peaceiris/actions-gh-pagesv3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./_site配置Webhook通知如钉钉机器人- name: Notify DingTalk uses: appleboy/telegram-actionmaster with: to: ${{ secrets.DINGTALK_TOKEN }} message: 博客更新已部署: https://yourblog.com4.3 内容搜索优化Jekyll静态博客需要额外配置搜索功能使用Algolia实现实时搜索// _includes/search.html const search instantsearch({ appId: YOUR_APP_ID, apiKey: YOUR_SEARCH_KEY, indexName: blog });自动同步索引的GitHub Action- name: Update Algolia Index uses: jekyll/algoliav1 with: application_id: ${{ secrets.ALGOLIA_APP_ID }} api_key: ${{ secrets.ALGOLIA_API_KEY }}本地测试搜索功能ALGOLIA_APP_IDxxx ALGOLIA_API_KEYxxx bundle exec jekyll algolia5. 常见问题解决方案5.1 构建失败排查遇到构建错误时按这个流程排查查看GitHub Actions日志gh run list --workflowpages gh run view --log本地复现问题bundle install JEKYLL_ENVproduction bundle exec jekyll build --trace常见错误处理插件冲突编辑Gemfile锁定版本语法错误使用markdownlint检查路径问题设置正确的baseurl我整理了一份常见错误代码对照表错误代码原因解决方案404资源路径错误检查baseurl和permalink设置500插件执行失败禁用非官方插件空白页面Liquid语法错误运行jekyll build --traceCSS丢失相对路径配置错误使用{{ site.baseurl }}前缀5.2 评论系统迁移静态博客的评论系统需要特殊处理Disqus迁移方案script var disqus_config function () { this.page.url {{ site.url }}{{ page.url }}; this.page.identifier {{ page.id }}; }; /script国内替代方案如Valinenew Valine({ el: #vcomments, appId: YOUR_LEANCLOUD_APP_ID, appKey: YOUR_LEANCLOUD_APP_KEY })自建方案基于GitHub Issues# _config.yml gitalk: clientID: YOUR_GITHUB_OAUTH_ID clientSecret: YOUR_GITHUB_OAUTH_SECRET repo: blog-comments owner: yourname我最终选择了Utterances因为它直接使用GitHub Issues存储评论无需额外认证script srchttps://utteranc.es/client.js repousername/blog-comments issue-termpathname themegithub-light crossoriginanonymous async /script5.3 流量监控配置没有数据库的静态博客如何做数据分析使用Google Analytics!-- _includes/head.html -- script async srchttps://www.googletagmanager.com/gtag/js?idGA_MEASUREMENT_ID/script script window.dataLayer window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag(js, new Date()); gtag(config, GA_MEASUREMENT_ID); /script轻量级替代方案如Umamidocker run -d --name umami -p 3000:3000 ghcr.io/umami-software/umami:postgresql-latest生成访问统计图# 分析GitHub Traffic API数据 import requests from datetime import datetime url https://api.github.com/repos/username/username.github.io/traffic/views headers {Authorization: token YOUR_GITHUB_TOKEN} data requests.get(url, headersheaders).json() views {item[timestamp]: item[count] for item in data[views]}6. 进阶本地化部署方案6.1 Docker容器部署对于需要完全掌控的场景可以本地部署创建DockerfileFROM jekyll/jekyll:4.2.0 COPY . /srv/jekyll RUN bundle install EXPOSE 4000 CMD [jekyll, serve, --force_polling]构建并运行docker build -t myblog . docker run -p 4000:4000 -v $(pwd):/srv/jekyll myblog生产环境部署Nginxserver { listen 80; server_name yourdomain.com; location / { proxy_pass http://localhost:4000; proxy_set_header Host $host; } }6.2 自动化备份策略保护数据安全的三个关键措施本地定时备份# 每周日凌晨3点执行 0 3 * * 0 tar -czvf /backups/blog_$(date %Y%m%d).tar.gz /path/to/blog同步到云存储rclone copy /backups remote:blog-backups --progress数据库备份如果有pg_dump -U postgres blog_db | gzip blog_db_$(date %Y%m%d).sql.gz我使用这个Python脚本自动清理旧备份import os import time from datetime import datetime, timedelta for file in os.listdir(/backups): path os.path.join(/backups, file) ctime datetime.fromtimestamp(os.path.getctime(path)) if datetime.now() - ctime timedelta(days30): os.remove(path)6.3 多平台同步方案实现一次写作多处发布使用Git Submodule管理主题git submodule add https://github.com/daattali/beautiful-jekyll自动化同步脚本import shutil import frontmatter def sync_to_platforms(post_path): post frontmatter.load(post_path) # 同步到Medium if medium in post.metadata.get(platforms, []): publish_to_medium(post) # 同步到知乎 if zhihu in post.metadata.get(platforms, []): publish_to_zhihu(post)RSS自动生成!-- feed.xml -- rss version2.0 channel title{{ site.title }}/title {% for post in site.posts limit:10 %} item title{{ post.title }}/title link{{ site.url }}{{ post.url }}/link description{{ post.content | xml_escape }}/description /item {% endfor %} /channel /rss迁移过程中最大的收获是养成了完善的备份习惯。现在我的写作流程变成了本地Markdown写作 → Git版本控制 → 自动构建部署 → 多平台同步。这种工作流不仅安全可靠还能让我专注于内容创作本身。