部署个人博客
本文详细介绍了如何搭建一个自己的个人博客网站,以及网站的后期维护、git 的自动拉取等进阶功能
[TOC]
1. 前言
1)背景
“拥有一个自己的网站” 这个想法已经在我脑子里存在快两年了,但总是在我想推进的时候有别的更紧急的事情冒出来,所以整体战线拖得很长。到今天个人博客才初步搭建成功,也总算是实现了曾经的想法。
后面会将之前写过的所有技术相关的文档都迁移到个人博客上,还会围绕个人博客做一些小的开发,比如说博客界面的优化、评论服务和同步服务的搭建等。
关于个人网站的一些时间节点:
- 2024 年 5 月在阿里云租了 2c2g 的服务器;
- 2024 年 8 月注册了第一个域名,写出了个人网站的第一个主页;
- 2024 年 11 月搭建了 memos,开始在 memos 上写一些随笔;
- 2025 年 5 月注册了第二个域名,并将所有内容都迁移到了第二个域名上;
- 2025 年 11月搭建了个人博客。
2)目标
在云服务器上搭建一个个人博客,实现以下目标:
- 云同步:保证在家里、单位、老家等不同的电脑上,都能实时获取最新的个人文档。
- 归档:将所有的个人文档进行整理、分类、加标签、归档,以便以后快捷查阅。
- 查阅:只要有网络的地方就可以快速查阅自己的文档,非常之方便。
- 分享:可以通过 url 分享自己的文档,方便快捷且高大上。
3)环境
- 服务器:阿里云服务器,2c2g,Ubuntu
- 本地:Windows 系统,Typora 编辑文档,git 同步文件。
- 云同步:GitCode(本来想用 GitHub,但是服务器上总是 fetch 失败,所以换成了 GitCode)
- 博客生成:Jekyll(使用了主题)生成静态 html 页面。
- 域名:使用自己之前注册的域名,新增了一个子域名,通过阿里云托管,服务器使用 Nginx 代理。
4)使用方法
按照本文档搭建成功后,通过以下方式操作来使用:
-
全流程自动实现:按照本文操作完全部后,全部流程可自动实现。即:本地在 Typora 中修改并保存后,修改内容会定时自动同步到 gitcode ,服务器会自动从 git 拉取最新文档,然后生成最新的 blog 页面并更新。
-
本地自动同步:现在已经搭建好了整体流程,本地在 Typora 中修改并保存后,修改内容会定时自动同步到 git 。(通过 “ bat 脚本” + “ Windows 自动任务” 实现的)
-
本地手动提交:若需要手动提交,在 Typora 中修改并保存后,可使用以下命令实现:
1 2 3 4
cd E:\AllMyMarkdown\blog-gitcode # 最好是全英文路径 git add . git commit -m 修改记录 git push
-
服务器自动更新:现在已经搭建好了整体流程,本地在 git 上 push 成功后,服务器上会自动完成 “git 拉取 + Jekyll 生成” 这两步,实现自动更新 blog 网站页面。
-
服务器手动更新:若需要在服务器上手动完成更新,可通过以下命令直接调用脚本实现:
1 2
cd /var/myblog ./abuild.sh -
服务器手动同步git:通过以下命令实现:
1 2 3 4 5 6 7
cd /var/myblog/mdFromGithub/blog-gitcode # 拉取最新分支: git pull # 将服务器的修改推送到git: git add . git commit -m 修改信息 git push
-
服务器手动生成页面:若修改了网站配置,通过以下命令直接生成 html 页面:
1 2
cd /var/myblog/blog jekyll build -
【占位】
2. blog 快速实现
本章可以快速实现在云服务器上使用 Jekyll 搭建一个个人博客。
1)Jekyll 安装
- Jekyll 基于 Ruby,需安装 Ruby 环境。Linux 命令如下:
1
2
sudo apt update
sudo apt install ruby-full build-essential zlib1g-dev
- 配置 RubyGems 路径,以避免权限问题(下面的文本也可以通过VSCode直接复制到 ~/.bashrc 文件中)
1
2
3
4
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
- 将 RubyGems 源替换为国内镜像,如淘宝镜像源,否则后面下载会卡顿导致失败:
1
2
gem sources --remove https://rubygems.org/
gem source -a https://gems.ruby-china.com/
- 安装 Jekyll 和 Bundler:
1
gem install jekyll bundler
- 验证安装:
1
jekyll -v # 输出版本号即成功
2)Nginx 安装
因为我的服务器上已经安装好了 Nginx,所以此步骤在本文略过。
Nginx 的安装和环境配置可以参考另一篇文章《从零开始搭建自己的网站》。
3)修改 Nginx 配置
- 向 Nginx 的配置文件
/etc/nginx/conf.d/klizzard.top.conf中添加如下内容:
1
2
3
4
5
6
7
8
server {
listen 80;
server_name www.blog.klizzard.top; # 子域名
location / {
root /var/myblog/blog/_site; # 静态文档的所在路径(直接使用jekyll的build路径)
index index.html index.htm; # 首页
}
}
- 测试 Nginx 配置文件的语法正确性:
1
sudo nginx -t
- 重新加载 Nginx 配置,使配置生效:
1
sudo systemctl reload nginx
- 重启nginx:
1
sudo systemctl restart nginx
- 本地预览(可选):打开目标端口的防火墙,在 bash 中输入以下命令后,在浏览器输入
http://服务器IP:4000,就能看到博客的实际效果。预览没问题后,按Ctrl+C停止预览服务。
1
2
# 启动本地预览服务(--host 0.0.0.0 允许通过服务器 IP 访问)
jekyll serve --host 0.0.0.0
4)添加域名解析
为保证外部能通过域名直接访问网站,需要在阿里云上为子域名添加解析,如下图所示:
5)为域名配置HTTPS
我的主域名已经用 Certbot 配置了 HTTPS,博客使用的子域名也可以用同一份证书(Let’s Encrypt 支持多域名),步骤如下:
- 执行以下命令,将子域名添加到现有证书中(Certbot 会自动处理配置):
1
2
3
4
5
# 关键:-d 参数后依次列出所有需要 HTTPS 的域名(主域名+子域名)
sudo certbot --nginx \
-d klizzard.top \
-d www.klizzard.top \
-d www.blog.klizzard.top
- 执行命令后的操作:
- 若提示 “是否扩展现有证书”,选择 E(Expand)。
- 若提示 “是否将 HTTP 重定向到 HTTPS”,选择 2(Redirect),自动完成 HTTP -> HTTPS 跳转。
-
Certbot 会自动修改
klizzard.top.conf文件,为两个子域名添加 HTTPS 配置。 - 最后参考前面的步骤重新验证 Nginx 的配置并生效。
3. 应用 Jekyll 主题
上一章完成后,就可以通过域名访问到个人博客了,但不够美观,考虑使用主题优化界面,也就是本章内容。
1)推荐主题
Jekyll 有很多主题可以选择,下面是网上一些使用量比较大的主题:
| 主题名称 | 特点 | 适用场景 | 官方文档/仓库 |
|---|---|---|---|
| Chirpy | 暗黑模式、代码高亮、目录导航、响应式 | 技术博客、程序员笔记 | GitHub 仓库 |
| Minimal Mistakes | 高度自定义、多布局、支持评论/分享 | 个人博客、生活记录 | GitHub 仓库 |
| PaperMod | 极简风格、加载快、支持标签/分类 | 轻量博客、内容优先 | GitHub 仓库(Jekyll 分支) |
测试了几个主题,最后决定采用功能较多、界面美观的 Chirpy 作为博客的主题。
2)应用 Chirpy 主题
1:下载 Chirpy 主题并初始化新项目
Chirpy 提供「快速启动模板」,直接下载即可用:
1
2
3
4
5
6
# 1. 克隆 Chirpy 模板到新的 blog 目录(即原项目路径)
git clone https://github.com/cotes2020/chirpy-starter.git blog
# 2. 进入新项目目录
cd blog
# 3. 安装主题依赖,添加verbase命令可以显示详细进度
bundle install --verbose
- 上面执行最后一个命令后需要等待一段时间
- 如果提示「Ruby 版本不足」(Chirpy 要求 Ruby ≥ 3.1.0),可参考「其它」章节切换版本。
2:添加 md 文章(把旧文章迁移到新主题)
- 将个人文章复制到项目的
_posts/即可:
1
2
# 复制所有 Markdown 文章到新主题的 _posts 目录
cp /var/myblog/blog_old/_posts/*.md /var/myblog/blog/_posts/
- 注意:Chirpy 对文章「Front Matter」有轻微要求(需包含
layout: post),如果原文章没有,可批量添加(示例):
1
2
3
4
5
6
7
---
title: "文章标题"
date: 2025-10-15 10:00:00
categories: 技术
tags: [Jekyll, Linux]
layout: post # 新增这行,确保主题识别为文章
---
3:配置主题核心参数
用文本编辑器打开新项目的 _config.yml,修改关键配置(其他参数可默认,后续再调):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 网站基础信息(替换成个人信息)
title: Klizzard 的博客 # 博客标题(显示在顶部)
tagline: 记录技术与生活 # 副标题
description: 分享 Linux、Jekyll 相关笔记
url: https://www.blog.klizzard.top # 博客子域名(必须正确)
baseurl: "" # 子域名根路径,留空
# 2. 作者信息(显示在文章底部)
author:
name: Klizzard
email: 邮箱@xxx.com
github: GitHub 用户名(可选,显示 GitHub 图标)
# 3. 主题功能配置(按需开启)
darkmode: auto # 自动切换暗黑模式(auto/light/dark)
toc: true # 文章自动生成目录
math: false # 不需要数学公式可设为 false
4:生成静态文件并验证效果
1
2
3
4
# 1. 生成静态文件(输出到 _site 目录,和原项目路径一致)
jekyll build
# 2. 本地预览(可选,确认样式没问题)
jekyll serve --host 0.0.0.0
- 预览时访问
http://服务器IP:4000,能看到 Chirpy 的默认样式,说明主题生效。
3)自定义主题样式(按需调整)
如果想进一步优化外观,可修改以下内容:
-
更换头像/封面图:
- 把头像图片命名为
avatar.jpg,放到assets/img/目录,主题会自动识别。 - 封面图:在
_config.yml中添加cover: /assets/img/cover.jpg(图片放到对应路径)。
- 把头像图片命名为
-
修改颜色方案:
- 编辑
assets/css/_variables.scss文件,修改$primary-color(主色调)、$secondary-color(辅助色)等变量,比如把主色调改成蓝色:$primary-color: #2563eb;。
- 编辑
-
添加导航菜单**:
-
在
_data/navigation.yml中添加菜单,比如新增「关于我」页面:1 2
- title: 关于 url: /about/
-
然后在
_tabs/目录新建about.md,编写关于页内容。
-
4)修改开源 url(本章节弃用,见下一章节)
因为 jekyll 及其主题中都使用了很多国外的开源项目 url,在国内使用有时候会页面加载失败。
所以需要手动将所有国外资源替换为国内稳定 CDN,以修复因资源加载失败导致的功能异常。
代码位置解释:blog 文章所在的路径是 fetch 的 chirpy-starter 的源码,也就是 Chirpy 主题的 “starter 模板”,其中不包含主题核心代码。主题是通过
Gemfile依赖jekyll-theme-chirpy这个 gem 包(主题核心逻辑在 gem 包里,不在 blog 项目目录)。因此需要先找到 Jekyll 使用的源码位置,直接修改源码。
执行命令定位主题核心代码的位置:
1
bundle show jekyll-theme-chirpy
输出类似:
1
/root/gems/gems/jekyll-theme-chirpy-7.4.0
进入上面查到的 gem 包目录,搜索 Bootstrap 的引用(这里才是主题核心配置):
1
2
3
# 搜索 CDN 配置(通常在 _data 或 _includes 目录)
grep -r "cdn" ./_data ./_includes
grep -r "https://cdn.bootcdn.net/ajax/libs/" ./_data ./_includes
检查其中使用的开源项目,很多开源项目可以在国内网站 bootcdn 或 staticfile中找到替代,拷贝 url 替换即可。
修改完成后,切换回 blog 的路径,执行以下命令重新构建网站:
1
2
3
4
cd /var/myblog/blog
bundle install # 安装依赖
bundle exec jekyll serve # 启动服务(这一步不需要
jekyll build # 重新生成一下网站
最后在浏览器上 F12 通过 “网络” 选项查看各配置项的是否加载成功,以及加载速度,然后再不停地修改迭代。
目前修过的所有文件如下所示:
1
2
3
4
5
6
7
8
9
10
11
jekyll-theme-chirpy-7.4.0/
├── _data/
│ └── origin/
│ └── cors.yml # 核心资源配置文件:将所有资源链接替换为国内CDN
├── _includes/
│ ├── analytics/
│ │ └── fathom.html # 网站统计功能:都注释掉,找不到国内替代也不需要这个功能
│ ├── jsdelivr-combine.html # 删除合并逻辑,改为逐个加载JS资源,解决国内CDN合并链接404问题
│ ├── post-sharing.html # 文章分享功能模板:修改为国内 cdn
│ ├── js-selector.html # JS资源选择与加载逻辑模板:修改为国内 cdn
└── └── head.html # 网页头部资源引用模板:修改为国内 cdn
修改并验证过的包在服务器上有备份,路径为:
/root/gems/gems/jekyll-theme-chirpy-7.4.0-改为国内url-bak
5)自托管静态资源
不管是 Jekyll 还是 Chirpy 都需要用到一些静态资源,在 Jekyll 的源码中,这些静态资源是通过 url 从外部拉取的,这样的好处是可以减少自己服务器的负载,坏处是国内经常会拉取失败(因为这些资源的 url 都是外网的)。上一章节是通过自己修改 Chirpy 源码中资源的 url 来解决这一问题。
但后来发现 Chirpy 的作者已经为 Chirpy Jekyll 主题 提供了一个静态资源支持的项目,包含主题运行所需的各类库、插件和网络字体等资源。它允许用户在生产环境或开发模式中选择自托管这些静态资源。链接如下:
因为我仅需要在本地开发中使用这些资源,按照作者的介绍,我需要的操作步骤很简单:
- 进入网站根目录,按如下方式克隆资源:
1 2 3
cd /var/myblog/blog/assets git submodule init git submodule update - 然后修改网站配置选项文件
_config.yml:1 2 3 4 5
# _config.yml 修改如下选项: assets: self_host: enabled: true env: development
如果希望网站发布时自托管资源,需要修改的内容不同,但我不需要,因此这里不再介绍,如果需要的话可以看作者在该项目中的 README.md。
6)更新主题
当前使用的主题是 Chirpy ,该主题通过 github 迭代,更新过程如下:
-
在服务器上切换到博客路径下:
1
cd /var/myblog/blog -
检查主题版本状态:
1
git status
-
若发现 git 版本落后的话,就拉取最新代码并合并:
1 2
git fetch # 因为网络问题可能会拉取失败,多试几次就行了 git merge -
重新构建:(安装主题依赖 + 网站构建)
1 2
bundle install jekyll build
4. 使用 git 同步
为了实现本地文档到云服务器的快捷部署,采用 gitcode 仓库做多端的同步。(本来一开始是用的 github,但是服务器上总是 fetch 失败,所以改为了 gitcode,但是问题不大,操作步骤和思路基本都是一样的)
1)gitcode仓库建立
首先在 gitcode上建立一个仓库,实现服务器与本地文档的同步。
2)win 本地
在本地新建一个路径,通过以下命令将 gitcode 仓库拉到本地。
1
git clone https://gitcode.com/Klizzardy/blog.git
然后在本地修改 md 文档,可以通过以下命令将修改同步到 gitcode 上。
1
2
3
git add .
git commit -m "初始化博客文章"
git push origin main
3)Ubuntu 自动脚本
服务器上已经编写好脚本,实现了 “git 拉取 + jekyll 搭建” 的过程,脚本内容如下:(以服务器运行版本为准)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# 1. 遇错即停:脚本中任何命令失败,立即退出(避免误判成功)
set -e
# 2. 添加 jekyll 所在目录到环境变量(替换为第一步找到的目录)
export PATH=$PATH:/root/gems/bin/jekyll
# (可选:若还有其他命令找不到,也可添加其目录,比如 git 路径,若 git 正常可省略)
# 进入文章仓库目录拉取最新内容
cd /var/myblog/mdFromGithub/blog-gitcode
git pull origin main
# 先清空生成路径下的所有文件:
rm -rf /var/myblog/blog/_posts/*
# 将git中的所有文件拷贝到jekyll指定路径下
cp -r /var/myblog/mdFromGithub/blog-gitcode/* /var/myblog/blog/_posts/
# 进入主题目录清理旧文件并重建
cd /var/myblog/blog
jekyll clean && jekyll build
echo "=========================== 博客更新完成!================================="
需要注意的是,.sh 脚本需要添加执行权限,然后才能直接在 bash 中直接执行:
1
chmod +x abuild.sh
5. Flask 服务自动更新 blog
此章节是为了实现:“gitcode 上有最新的提交后,服务器会自动 fetch 最新代码,并自动完成网站的更新”。
具体操作步骤见文档: 写一个Flask服务响应WebHook
6. 本地 git 自动同步
2025年11月25日:弃用此节的方法,改为用 go 写一个微服务,可以实现 git 定时同步、开机自启动、使用方无感(不会乱弹 cmd 窗口)。详见文章:用go实现git自动同步服务
2025年11月08日:按照本节操作完成后,会定时同步 git,但是每次执行脚本的时候都会闪出来一个黑色的 cmd 窗口,很不优雅。尝试用 VBscript 脚本,但是没有成功,后续有空再研究一下怎么优雅实现吧。
win 本地通过 bat 脚本 + Windows 的任务计划实现。
autoPushGit.bat 脚本内容如下:(以gitcode 上的版本为准)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@echo off
:: 隐藏CMD窗口(静默运行)
if "%1"=="h" goto begin
start mshta vbscript:createobject("wscript.shell").run("""%~f0"" h",0)(window.close)&&exit
:begin
chcp 65001 >nul 2>&1
:: 配置路径(仓库路径和日志目录)
set "REPO_PATH=E:\AllMyMarkdown\blog-gitcode"
set "LOG_DIR=E:\AllMyMarkdown\autoPushGit_log"
set "LOG_FILE=%LOG_DIR%\git_sync.log"
:: 确保日志目录存在(不存在则创建,增加错误判断)
if not exist "%LOG_DIR%" (
md "%LOG_DIR%" >nul 2>&1
if errorlevel 1 (
echo [ERROR] 无法创建日志目录 "%LOG_DIR%",请检查权限 >> "%USERPROFILE%\Desktop\git_sync_error.log"
exit /b 1
)
)
:: 获取统一格式的当前时间(避免系统时间格式差异)
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "NOW=%dt:~0,4%-%dt:~4,2%-%dt:~6,2% %dt:~8,2%:%dt:~10,2%:%dt:~12,2%"
:: 记录执行开始(增加分隔线,日志更清晰)
echo ============================================== >> "%LOG_FILE%"
echo [%NOW%] 脚本开始执行 >> "%LOG_FILE%"
echo [仓库路径] %REPO_PATH% >> "%LOG_FILE%"
:: 切换到仓库目录(增加详细错误日志)
cd /d "%REPO_PATH%" || (
echo [%NOW%] 错误:无法切换到仓库目录 "%REPO_PATH%" >> "%LOG_FILE%"
echo [%NOW%] 可能原因:路径不存在或权限不足 >> "%LOG_FILE%"
echo [%NOW%] 脚本执行失败 >> "%LOG_FILE%"
echo ============================================== >> "%LOG_FILE%"
echo. >> "%LOG_FILE%"
exit /b 1
)
:: 检查是否为Git仓库(增加前置判断)
if not exist ".git\" (
echo [%NOW%] 错误:"%REPO_PATH%" 不是Git仓库(未找到.git文件夹) >> "%LOG_FILE%"
echo [%NOW%] 脚本执行失败 >> "%LOG_FILE%"
echo ============================================== >> "%LOG_FILE%"
echo. >> "%LOG_FILE%"
exit /b 1
)
:: 拉取远程代码(输出详细结果到日志,方便排查冲突)
echo [%NOW%] 开始执行 git pull... >> "%LOG_FILE%"
git pull >> "%LOG_FILE%" 2>&1
if errorlevel 1 (
echo [%NOW%] 警告:git pull 执行失败(可能存在冲突或网络问题) >> "%LOG_FILE%"
) else (
echo [%NOW%] git pull 执行成功 >> "%LOG_FILE%"
)
:: 检查工作区是否有变更(优化判断逻辑)
git diff --quiet --exit-code
if %errorlevel% equ 0 (
:: 无任何变更,直接结束
echo [%NOW%] 工作区无变更,无需提交和推送 >> "%LOG_FILE%"
) else (
:: 有变更:添加到暂存区并提交推送(分步记录日志)
echo [%NOW%] 检测到变更,开始执行 add、commit、push... >> "%LOG_FILE%"
git add . >> "%LOG_FILE%" 2>&1
git commit -m "JJ-Windows自动提交 [%NOW%]" >> "%LOG_FILE%" 2>&1
git push >> "%LOG_FILE%" 2>&1
if errorlevel 1 (
echo [%NOW%] 警告:commit或push执行失败,请查看日志 >> "%LOG_FILE%"
) else (
echo [%NOW%] add/commit/push 执行成功 >> "%LOG_FILE%"
)
)
:: 记录执行结束
echo [%NOW%] 脚本执行结束 >> "%LOG_FILE%"
echo ============================================== >> "%LOG_FILE%"
echo. >> "%LOG_FILE%"
将上述代码拷贝到 .bat 脚本中,放到指定位置,并配置好 Windows 自动任务(参考 Typora的多端同步方案,如何多台计算机共享md文件?Windows和Mac通过定时执行git来同步markdown文件 - 压中 - 博客园)。即可实现自动同步 git 的功能。
执行记录见日志:E:\AllMyMarkdown\autoPushGit_log\git_sync.log。
7. 其它
1)升级 Ruby 版本
在使用 Jekyll 的一些主题时,可能会对 Ruby 版本有要求,此时需要升级 Ruby 版本。
使用 rvm(Ruby Version Manager)来安装和管理 Ruby 版本。
1
2
3
4
5
6
7
8
# 导入 RVM 公钥
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
# 安装 RVM
curl -sSL https://get.rvm.io | bash -s stable
# 加载 RVM 环境(下面的路径是我安装的rvm路径,在其他设备上按需修改)
source /usr/local/rvm/bin/rvm
修改用户配置使高级版生效:
也可以直接编辑 .bashrc 文件,在文件最后添加:
1
2
3
4
5
6
7
8
# 1. 加载 RVM 环境
source /usr/local/rvm/scripts/rvm
# 2. 将 Ruby 3.1.4 的可执行目录添加到 PATH 最前面(优先使用)
export PATH="/usr/local/rvm/rubies/ruby-3.1.4/bin/$PATH"
# 3. 配置 RubyGems 路径(避免权限问题)
# Install Ruby Gems to ~/gems#
export GEM_HOME="$HOME/gems"
export PATH="$HOME/gems/bin:$PATH"
保存并生效:
1
2
3
4
5
6
# 加载修改后的 .bashrc
source ~/.bashrc
# 验证:默认 Ruby 版本是否为 3.1.4
ruby -v # 输出 ruby 3.1.4p223 (...) 即成功
bundle -v # 也会关联到 3.1.4 版本的 Bundler
修改全局配置:
或者修改全局配置文件/etc/profile,以全局生效(所有用户,包括 root),在文件末尾添加以下内容:
1
2
source /usr/local/rvm/scripts/rvm
export PATH="/usr/local/rvm/rubies/ruby-3.1.4/bin:$PATH"
保存并让所有用户生效:
1
2
3
4
5
6
# 让当前终端立即生效
source /etc/profile
# 切换到任意用户(包括 root)验证
su - root
ruby -v # 输出 3.1.4 即成功
2)卸载 Ruby 旧版本
因为安装了 Ruby 新版本后在执行 bundle install --verbose 命令时还是会默认使用旧版本来执行,从而导致主题无法生效。因此这里选择直接卸载老版本的 Ruby 3.0.2 及其配套的软件。
- 首先执行命令,查看哪些系统包依赖 Ruby 3.0.2,若依赖较少再卸载:
1
2
# 查看系统中依赖 ruby3.0 的包(3.0.2 通常对应包名 ruby3.0)
sudo apt rdepends ruby3.0
- 先卸载 Ruby 3.0.2 及关联包
1
2
3
4
5
6
7
8
# 卸载系统默认 Ruby 3.0.2 及开发包(避免残留)
sudo apt remove -y ruby3.0 ruby3.0-dev
# 清除残留的配置文件(彻底卸载)
sudo apt purge -y ruby3.0 ruby3.0-dev
# 清理无用依赖(可选,删除因 Ruby 3.0.2 安装的依赖包)
sudo apt autoremove -y
- 验证旧版本是否已卸载
1
2
3
4
5
6
7
# 检查系统是否仍有 Ruby 3.0.2 残留
ruby3.0 -v
# 若输出“ruby3.0: command not found”,说明卸载成功
# 再次确认当前 Ruby 版本(仍为 3.1.4)
ruby -v
# 正确输出:ruby 3.1.4p223 (...)
- 先卸载旧 Bundler
1
2
3
# 卸载所有 Bundler 版本(-x 表示强制清除)
gem uninstall bundler -x
# 若提示“没有安装 Bundler”,直接跳过这步
- 重新安装 Bundler(确保与 3.1.4 绑定)
1
2
3
4
5
# 安装最新版 Bundler(自动和当前 3.1.4 绑定)
gem install bundler --verbose
# 安装成功后,查看 Bundler 版本(确保是 2.6+)
bundle -v
# 输出类似“Bundler version 2.6.2”即正常
3)修改图片路径
本地 md 文档中的图片都位于相对路径 ${img4md}/* 中,如果不管图片路径的话,直接生成的 html 中图片都是无法浏览的。因此需要对图片和图片路径做修改:
在 abuild.sh 中新增如下内容,实现 “图片拷贝 + 文本内容替换” 的操作:
1
2
3
4
5
6
7
8
9
10
# 拷贝图片到 Jekyll 的 assets/images 目录:
mkdir -p /var/myblog/blog/assets/images # 确保目标目录存在
# 清空旧图片(避免冗余)
rm -rf /var/myblog/blog/assets/images/*
# 从 Git 仓库的 img4md 目录拷贝图片到目标目录
cp -r /var/myblog/mdFromGithub/blog-gitcode/\/assets/images/* /var/myblog/blog/assets/images/
# 为保证md中的图片转成html后还能正常显示:
# 使用 sed 命令,替换所有 MD 文件中的 /assets/images 为 /assets/images
sed -i 's/\$[{]img4md[}]/\/assets\/images/g' /var/myblog/blog/_posts/*.md
完整的 abuild.sh 内容见服务器上的文件 /var/myblog/abuild.sh。
4)mermaid 图表
在 md 文档最上方 YAML 块中添加 mermaid: true 就可以了
5)md 文档书写规则
详见 Chirpy 的介绍网站 Chirpy
另外有一些注意点:
- 标题需要从 2 级开始,这样 build 出来的项目在网页上浏览时导航栏的显示才是正确的。
- 文档结尾的参考文档如果上面没有引用过的话,会被隐藏不显示。(看看能不能解决这个问题
- 表格上方需要有空行,否则转为 html 的时候会识别失败。
- 链接中不要加竖号
|,例如[文章1 | Klizzz's blog](https:xxxxx),否则不会识别为链接。 - 代码块的类型不能是
cmd,blog 不识别这个类型,会显示为普通文字。用bash就可以。
6)修改第三方小图标
不管是 memos 还是个人 blog,或者是 index,如果想修改上面那些小图标的话,可以先看一下使用的第三方资源库中有没有:Font Awesome
7)添加备案信息
在如下路径新建一个 footer.html 文件:
1
/var/myblog/blog/_includes/footer.html
从源码中拷贝 footer.html 到新文件中,然后添加备案信息,源码位置:
1
/root/gems/gems/jekyll-theme-chirpy-7.4.1/_includes/footer.html
新增的备案信息:(具体以服务器上运行代码版本为准)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 中间:备案信息(新增) -->
<div class="text-center mb-2 mb-lg-0 flex-grow-1">
<div class="beian-info" style="font-size: 0.8rem; color: #6c757d; line-height: 1.3;">
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener"
style="color: inherit; text-decoration: none;">
京ICP备2024081088号-2
</a>
<span style="margin: 0 8px; color: #adb5bd;">|</span>
<a href="http://www.beian.gov.cn/portal/registerSystemInfo" target="_blank" rel="noopener"
style="color: inherit; text-decoration: none;">
<img src="/assets/img/beian.png" alt="公安备案"
style="height: 12px; width: 12px; vertical-align: text-bottom; margin-right: 3px;">
京公网安备11010802046851号
</a>
</div>
</div>
之前的页脚:
修改后的页脚:
8. 名词解释
Jekyll
Jekyll 是一个 静态网站生成器,它能将纯文本(如 Markdown、HTML)通过模板引擎转换为完整的静态 HTML 网站,无需数据库支持,非常适合搭建博客、文档网站或个人主页。
简单来说,它的核心作用是:用简单的文本格式写内容,自动生成可直接部署的静态网页,省去手动编写大量重复 HTML 代码的麻烦。
Jekyll 的核心特点:
-
静态网站输出 :最终生成的是纯 HTML/CSS/JS 文件,没有动态脚本或数据库,因此:
- 加载速度极快(直接从服务器读取文件,无需计算)
- 安全性高(没有数据库注入、动态脚本漏洞等风险)
- 部署简单(可托管在 GitHub Pages、Netlify 等平台,甚至普通服务器)
-
基于模板和变量的自动化 :
可以定义通用模板(如页眉、页脚、侧边栏),然后在不同页面中复用,避免重复编写相同代码。
例如:用
Klizzz's blog表示网站标题,修改配置文件后所有页面会自动更新。 -
支持 Markdown 写作
博客文章可以用 Markdown 格式编写(语法简单,适合程序员),Jekyll 会自动将其转换为结构化的 HTML。
文件名遵循
YYYY-MM-DD-文章标题.md格式时,会被自动识别为博客文章,并按日期排序。 -
与 Git 工作流无缝结合
写作流程可完全通过 Git 管理:
写文章(Markdown)→
git commit提交 → 自动生成静态文件 → 推送至服务器/平台发布,对程序员非常友好。 -
免费且开源
基于 Ruby 开发,完全开源,支持丰富的插件(如代码高亮、评论系统、RSS 生成等)。
Jekyll 的工作原理:
-
源文件结构
需要按固定目录结构组织文件:
1 2 3 4 5 6 7
博客目录/ ├── _posts/ # 存放 Markdown 格式的博客文章 ├── _layouts/ # 页面模板(如首页、文章页模板) ├── _includes/ # 可复用的组件(如页眉、页脚) ├── _config.yml # 全局配置(网站标题、作者等) ├── index.html # 首页 └── assets/ # 图片、CSS、JS 等静态资源
-
构建过程
运行
jekyll build命令后,Jekyll 会:- 读取
_config.yml中的全局配置 - 解析
_posts中的 Markdown 文章,提取标题、日期等元信息 - 将文章内容与
_layouts中的模板结合,生成完整 HTML - 把所有生成的文件输出到
_site目录(这个目录就是可直接部署的静态网站)
- 读取
-
本地预览
运行
jekyll serve可启动本地服务器(默认地址http://localhost:4000),修改文件后会自动重新生成,方便实时预览效果。
适合用 Jekyll 的场景:
- 个人技术博客(支持代码高亮,契合程序员写作习惯)
- 项目文档(可与 GitHub 仓库绑定,方便维护)
- 轻量级静态网站(如作品集、简历页)
如果需要复杂的动态功能(如用户登录、实时评论互动),Jekyll 可能不太适合(需结合第三方服务补充);但如果追求简单、快速、低维护成本的静态网站,Jekyll 是非常好的选择。
GitHub Pages 还对 Jekyll 提供原生支持——只要把 Jekyll 项目推送到 GitHub 仓库,就能自动构建并托管网站,完全免费,这也是很多开发者用它搭建博客的重要原因。
Ruby
Ruby 是一种简洁、优雅的编程语言,由松本行弘(Yukihiro Matsumoto)在 1995 年设计,强调“以人为本”的编程风格——代码读起来接近自然语言,可读性强,适合快速开发。
而 Jekyll 正是是 基于Ruby 开发的静态网站生成工具,它的核心功能就是通过 Ruby 代码实现的。简单来说,Jekyll 是 Ruby 生态中的一个“应用程序”,就像“微信是用 C++ 开发的社交软件”一样。
为什么 Jekyll 依赖 Ruby:
Jekyll 的工作原理本质上是通过 Ruby 代码完成以下操作:
- 解析配置:读取
_config.yml中的配置(如网站标题、域名等); - 处理模板:用 Ruby 的模板引擎(如 Liquid)解析 HTML 模板文件,动态生成页面结构;
- 转换文章:将
_posts目录中的 Markdown 文章(.md文件)转换为 HTML 静态页面; - 生成站点:整合所有资源(CSS、JS、图片等),最终输出可直接部署的静态网站(到
_site目录)。
两者的关系类比:
- Ruby 相当于“编程语言”(如中文);
- Jekyll 相当于“用 Ruby 写的工具”(如用中文写的一本“写作指南”);
- 用 Markdown 写博客文章,就像“按指南的规则写内容”,最终 Jekyll(通过 Ruby)把内容整理成美观的网页。
实际使用中的关联:
在安装 Jekyll 时,需要先安装 Ruby(就像用微信前需要先安装操作系统),因为 Jekyll 的代码依赖 Ruby 环境才能运行。例如:
gem install jekyll命令中,gem是 Ruby 的包管理工具(类似 Python 的pip);jekyll build命令的本质是通过 Ruby 解释器执行 Jekyll 的核心代码,完成静态网站生成。
简单说:Ruby 是底层语言,Jekyll 是用 Ruby 写的工具,专门用来快速生成博客等静态网站。
RVM
RVM 全称 Ruby Version Manager,是一款针对 Ruby 语言的版本管理工具,核心作用是在同一台服务器/电脑上,独立管理多个 Ruby 版本及对应依赖(Gems),避免版本冲突。
核心功能:
- 多 Ruby 版本切换:可同时安装多个 Ruby 版本(如 2.7、3.1、3.2),并按需切换默认版本,适配不同项目的 Ruby 版本需求。
- 隔离 Gem 环境:为每个 Ruby 版本或项目创建独立的 Gem 目录(类似 Python 的虚拟环境),避免不同项目的依赖包(Gem)互相干扰。
- 简化安装与升级:通过命令快速安装、升级 Ruby 版本及相关组件,无需手动处理编译依赖和环境配置。
常见使用场景:
- 开发/部署多个 Ruby 项目,且项目依赖不同的 Ruby 版本;
- 避免系统自带 Ruby 版本被修改,导致系统工具异常;
- 快速测试项目在不同 Ruby 版本下的兼容性。
关键注意点:
- 若仅使用单一 Ruby 版本(如当前用独立路径安装的 Ruby),则无需 RVM;
- 它会修改环境变量(如
PATH、GEM_PATH),可能与手动配置的 Ruby 环境冲突(这也是可能遇到 Jekyll 找不到的原因之一)。
bundle
bundle 是 Ruby 语言的依赖管理工具,类似 Python 的 pip 或 Node.js 的 npm,在本次操作中主要作用是:
-
管理 Jekyll 及插件的版本
通过
Gemfile记录需要的工具(如jekyll、jekyll-mermaid插件),bundle会自动下载并安装这些工具的指定版本,避免版本不兼容导致的错误(比如之前安装jekyll-mermaid插件时就需要用bundle install)。 -
确保环境一致性
执行
bundle exec jekyll build时,bundle会优先使用Gemfile中指定的工具版本,而不是系统全局安装的版本,保证构建博客时的环境稳定(比如避免系统中其他版本的 Jekyll 干扰)。
简单说,bundle 就是帮助 “管好” 运行 Jekyll 和相关插件所需的各种工具,确保它们能正常协同工作。
SSL
SSL 全称 Secure Sockets Layer(安全套接层),是一种用于在客户端(如浏览器)和服务器之间建立加密通信的安全协议。它的后续升级版本称为 TLS(Transport Layer Security,传输层安全),但日常场景中仍习惯统称“SSL”。
核心作用是解决网络通信的三大安全问题:
- 数据加密:将传输的数据加密,防止中途被窃取(比如黑客拦截网络数据后无法破解内容);
- 身份认证:通过 SSL 证书验证服务器的真实身份,避免访客访问伪造的钓鱼网站;
- 数据完整性:确保传输的数据未被篡改(比如黑客修改内容后会被检测到)。
在本次博客部署中,SSL 起到的关键作用:
- 保障 WebHook 请求的安全性:
- 原 WebHook 使用
http://IP:5000/update-blog(HTTP 协议),传输的数据(包括令牌、代码提交信息等)是明文的,存在被拦截、篡改的风险; - 改为
https://www.blog.klizzard.top/update-blog(HTTPS 协议,基于 SSL 实现)后,GitCode 发送的 WebHook 请求会被加密,即使数据中途被拦截,黑客也无法破解内容,确保令牌不泄露、请求内容不被篡改。
- 原 WebHook 使用
- 满足 GitCode WebHook 的安全要求:
- 部分代码托管平台(包括 GitCode)对 WebHook 的 Payload URL 有安全限制,优先支持 HTTPS 地址,甚至拒绝向 HTTP 地址发送请求。配置 SSL 后,能避免因“协议不安全”导致 WebHook 推送失败。
- 提升博客访问的可信度和安全性:
- 访客访问博客
https://www.blog.klizzard.top时,浏览器地址栏会显示小锁图标,表明连接是加密的,增强用户信任; - 避免浏览器弹出“不安全连接”的警告,提升访问体验(尤其是技术博客的访客,对网站安全性更敏感)。
- 访客访问博客
补充说明:
配置中用到的 SSL 证书由 Certbot 生成(Let’s Encrypt 提供的免费证书),Nginx 通过加载证书文件(fullchain.pem 和 privkey.pem)实现 HTTPS 服务。整个流程中,SSL 相当于在服务器和 GitCode/访客之间建立了一条“加密隧道”,所有数据通过隧道传输,保障了通信的安全性和可靠性。
Gem
在 Ruby 生态(尤其是 Jekyll 博客场景中),Gem 是 Ruby 语言的包管理格式,也是具体的软件包本身,类似于 JavaScript 的 npm 包、Python 的 pip 包,核心作用是封装、分发和管理 Ruby 相关的代码库、工具或框架。
一、Gem 的核心概念
- Gem 包:一个 Gem 本质是一个打包好的 Ruby 代码集合,包含了具体的功能实现(如库、工具类)、配置文件、文档等。比如 Jekyll 博客框架本身就是一个 Gem,
jekyll-theme-chirpy主题、jekyll-seo-tag插件也都是 Gem 包。 - RubyGems:是 Ruby 官方的包管理工具(类似 npm 对应 JavaScript),内置在 Ruby 环境中,提供了 Gem 包的搜索、安装、更新、卸载等核心功能。
- Gemfile & Gemfile.lock:
Gemfile:用于声明项目依赖的 Gem 包(版本、来源等),比如 Jekyll 博客的Gemfile会指定jekyll、主题 Gem、插件 Gem 等,类似package.json。Gemfile.lock:自动生成的文件,记录了实际安装的每个 Gem 包的精确版本,确保项目在不同环境下依赖一致,避免版本冲突。
二、Gem 在的Jekyll 博客中的实际应用 搭建博客时用到的核心工具和组件,几乎都是通过 Gem 管理的:
- 核心框架:
jekyllGem 提供了博客的构建、本地服务等核心功能,安装命令为gem install jekyll。 - 主题:
jekyll-theme-chirpy是一个主题 Gem,通过在Gemfile中声明并安装,就能将主题应用到博客。 - 插件:比如
jekyll-seo-tag(优化 SEO)、jekyll-sitemap(生成站点地图)等插件,也都是以 Gem 形式引入,扩展博客功能。 - 依赖安装:执行的
bundle install命令,本质是通过Bundler(Ruby 的依赖管理工具,本身也是 Gem)读取Gemfile,自动安装所有声明的依赖 Gem 包。
三、常用的 Gem 操作命令 在终端中可通过以下命令管理 Gem 包(适用于本文的博客维护):
| 命令 | 功能 | 示例 |
|---|---|---|
gem install [gem名] |
安装指定 Gem 包 | gem install jekyll |
gem uninstall [gem名] |
卸载指定 Gem 包 | gem uninstall jekyll-theme-chirpy |
gem update [gem名] |
更新指定 Gem 包(不加名则更新所有) | gem update jekyll |
gem list |
查看本地已安装的所有 Gem 包 | gem list jekyll(筛选查看 jekyll 相关) |
bundle install |
基于 Gemfile 安装项目依赖 | 进入博客目录执行,安装所有声明的 Gem |
bundle exec jekyll build |
通过 Bundler 执行 Jekyll 命令(确保使用项目依赖的 Gem 版本) | 构建博客静态文件 |
四、Gem 的来源(镜像源)
默认情况下,RubyGems 从国外官方源(https://rubygems.org/)下载包,国内访问可能较慢或不稳定,因此通常会切换到国内镜像源,比如:
- 阿里云 RubyGems 镜像:
https://mirrors.aliyun.com/rubygems/ - Ruby China 镜像:
https://gems.ruby-china.com/
切换镜像源的命令:
1
2
3
4
5
6
# 移除默认源
gem sources --remove https://rubygems.org/
# 添加国内镜像源
gem sources --add https://mirrors.aliyun.com/rubygems/
# 查看当前源
gem sources -l
切换后,安装和更新 Gem 包的速度会大幅提升,避免因网络问题导致的依赖安装失败。
五、总结
Gem 是 Ruby 生态的核心包管理机制,本文的 Jekyll 博客从框架到主题、插件,都依赖 Gem 实现功能封装和依赖管理。日常维护中,核心是通过 Gemfile 管理依赖,用 bundle 命令确保环境一致性,切换国内镜像源可解决网络加载问题。
9. TODO
- win本地通过git提交新的修改后,服务器自动拉取并更新博客。
- 将 webhook 中的 Payload URL 从 ip 修改为 https 域名,保证安全。
- bug:mermaid 图表显示不出来。(最上方 YAML 块中添加
mermaid: true就行了) - bug:插入的图片在html中显示不出来,怎么快捷拷贝?
- 补充 bundle 相关的信息
- 网站有时候会加载的很慢,通过F12发现是 bootstrap 网址获取失败导致的,怎样优化这个问题?
- 标签的整理和划分。
- 其它文档的整理。
- 公众号上的一些文章也可以整理到这里。
- 能否实现为工作文档添加权限?
- py 脚本的云同步和整理。能否实现在云服务器上快捷检索然后使用?
- 转译为html后的样式能否调整,我还是比较习惯代码块是深色的样子。保证和typora中一致最好。
- 增加评论区。这个 chirpy 是支持的,重点是解决国内如何使用的问题。
- 能否在win本地增加一个服务,实现md文档到git的自动同步
- 现在每篇文章右下角会有一个分享,但是分享都是推特、Facebook之类的,能否去掉或者换成别的
- 博客左下角的 “深/浅色切换按钮” 只在首页点击的时候管用,其它页面点击无效。
- 文章上方 “更新于” 这个时间的显示逻辑是啥?为啥有的显示有的不显示?显示的也不是最后修改时间
- 从浏览器打开 blog 网站,有时候第三方源还是会拉去不到或是延迟太高,能否将第三方源下载到本地?
- 从微信打开链接会提示风险提醒,想办法去掉



