用 Jekyll 快速搭建一个自己的网页并架设到服务器
设计思路
后端(back-end): GitHub 托管网页的代码, 网页中的图片素材使用 Cloudinary 存储. 前端(front-end): 目前使用 Jekyll.
Jekyll 同时支持 markdown 和 html 等格式进行编写. 对于有大量的文本输入的介绍类/博客类网页, 我认为用 md 来书写更加简单且纯粹, 因此我使用了支持 md + html 的 Jekyll. 对于网页的文本内容(博客/书单等), 我使用 md 编写; 而照片墙, 邮件系统的排版布局, 则使用 html. 类似 Jekyll 的还有 Wordpress 和 Hexo, 不选他们并不是因为他们不如 Jekyll, 主要是因为 Jekyll 是 GitHub 社区的产物, 我又是 GitHub 社区的深度用户, 因此对 Jekyll 比较有接触, 并且我觉得网页可以架设到 GitHub 的服务器上也是一个不错的feature, 因此你不一定需要有一个服务器就可以完成网页的架设. 很多例如 gitbooks, readthedocs 一类的文本型网页生成器也是基于 Jekyll.
操作流程
安装依赖
安装所需的软件(主要ruby)
Debian/Ubuntu
apt-get install ruby-full make gcc nodejs build-essential patch
Windows 平台下载 Ruby 安装即可.
安装 bundle 和 Jekyll (gem依赖ruby)
打开 Terminal/CMD/PWSH
$ gem install bundle jekyll
找模板, git clone 代码
通常来说, 我们首先会找到一个自己觉得不错的模板, 然后把该模板 Fork 到自己的账号里, 在模板的基础上在做修改(也可以用Jekyll建立新网页). Fork 后, 我们就可以把模板 clone 到本地了.
git clone https://github.com/$USERNAME/$REPOSITORY.git
分支开发(branch)*
分支开发为可选内容
, 如果不需要多分支可跳至下一标题.
插一嘴关于 branch: 为了保持网页开发的规范性, 与防止一些修改对网页造成较大的问题, 我们尽量不在没有进行足够多的测试时对 master 分支做修改. 因此我们创建一个 dev 分支, 保存当前开发的提交(commit)但是还未完成的内容. 此处不对 Git 的原理做详细叙述, 因为 Git 是一个全面且完整的版本管理工具, 无法三言两语说清楚, 因此仅做针对常用命令的最简说明. 详见 廖雪峰 - Git教程 创建与合并分支
创建 dev 分支
$ git branch dev
切换到 dev 分支
$ git checkout dev
Switched to branch 'dev'
此时针对 dev 分支进行 add / commit / push 合并分支 当开发的内容在本地测试完成后, 就可以并入 master 分支
- 切回 master 分支
$ git checkout master
Switched to branch 'master'
- 合并
$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
push同步主分支更新 大约2分钟后就可以在 GitHub 上看到更新后的网页的样子.
完成网页的修改
使用 md + html 语法完成网页的修改, 这部分内容不做展开, 仅提及一下 Markdown. Markdown 文法已经广泛使用于许多的场景, 尤其被广泛应用与说明文档中, Jupyter Notebook, GitHub 也支持 md 文法.
Markdown是一种轻量级标记语言,创始人为約翰·格魯伯(英語:John Gruber)。它允许人们“使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档”。这种语言吸收了很多在电子邮件中已有的纯文本标记的特性。
由於Markdown的輕量化、易讀易寫特性,並且對於圖片,圖表、數學式都有支援,目前許多網站都廣泛使用 Markdown 來撰寫說明文件或是用於論壇上發表訊息。例如:GitHub、reddit、Diaspora、Stack Exchange、OpenStreetMap 、SourceForge等。甚至Markdown能被使用來撰寫電子書。
– Wiki
推荐资料: GitHub 支援的 Markdown语法与实现
本地测试
在修改网页后, 我们可以在本地端测试一下网页.
先进入 Jekyll 网页根目录, 再执行此命令
$ bundle exec jekyll serve
此时, 浏览器进入 http://localhost:4000 ,就可以完成本地的测试. 测试成功后, 可参照 3. 分支开发(branch) 的内容同步至 GitHub 仓库中.
- 注意: 其中可能会遇到 You have already activated X, but your Gemfile requires Y 或是 This Gemfile requires a different version of Bundler 之类的版本问题. 主要是因为下载的软件版本与此网页的所需的版本不同. 给出几个解决方案: 可以通过安装该网页指定版本解决; 使用 bundle exec 作为命令头; 执行 bundle clean –force 后重试等方法解决. 这个问题是一个遗留问题, 因此 Stackoverflow, GitHub 等都有大量的解答, 很容易找答案顺利解决. 或者换一个新一点的 Jekyll 主题, 就不会出现这些问题了.
使用 GitHub 的服务器架设网页
我们通过 GitHub 托管代码, 也可以通过 GitHub 来架设或者预览我们的成果.
获得io域名(可选)
仓库名修改为 username.github.io , username写用户名或是组织名.
设置分支
在仓库设置里, 找到 GitHub Page 项, 切换分支. 本例中分支为 master. 有时是 docs, 有时是 gh-pages, 与你的仓库的分支设计有关.
此时, 我们就能在 https://username.github.io/ 上看到你的网页, 你可以把这个网页放到仓库的说明栏中.
私人服务器架设网页
如果你有自己的服务器, 你还可以把网页架设到你的服务器上.
找一个目录存放你的网页
$ cd /path/to/site
同步 GitHub 的代码到服务器
在经过以上步骤后, 此时网页在 GitHub 存在一个包含你的网页的仓库. 此处使用 git clone 下载上传到 GitHub 的网页代码. 当然也可以把本地./path/to/site/_site 目录下的文件直接复制到服务器上, 但是这样做每次更新内容都要手动更新比较麻烦.
$ git clone https://github.com/$USERNAME/$REPOSITORY.git
在服务器上安装 Jekyll
参照 1. 安装依赖. 之所以服务器上也要安装 Jekyll 是因为需要使用 jekyll build 命令生成 /_site 目录与此目录中的 html 代码. 此目录下内容是编译后的 html 代码, 可以单独使用, Jekyll 相当于编译器.
“编译”得到 html 代码
$ JEKYLL_ENV=production /usr/local/bin/jekyll build
注: 此命令表示在 production 环境下建立网页. 详见 Jekyll - Environments
此时生成的 /site 目录作为网页的 root 目录. 如果遇到问题, 请参照 5. 本地测试
nginx 框架设置
如果你的服务器使用的是 Nginx 框架, 你可以在 /etc/nginx/conf.d/default.conf 文件写入以下内容来架设网页. 你可以选用 http 或是 https 的规范.
- http: 简单, 不安全传输
root 填写你的网页存放的目录(执行git clone 的目录)加上 /_site , index 填写网站主页的文件, 通常为 index.html.
server {
listen 80;
listen [::]:80;
root /path/to/site/_site;
index index.html;
}
- https: 复杂, 安全传输(主流)
如何启用 https / 如何生成证书, 见 acme.sh获取Let’s Encrypt免费证书并自动更新
https 遵守 ssl/tls 安全传输协议, 因此需要密钥, 包括公钥和私钥(ssl_certificate & ssl_certificate_key). 可使用 certbot 或是 acme.sh脚本生成证书, 两者都支援 nginx, 应该不是很难弄. 如果使用 TLSv1.2 协议则还需要迪菲-赫爾曼密鑰 (ssl_dhparam)以防止中间人攻击(可选). OCSP stapling未配置. 完整配置详见: Mozilla SSL Configuration Generator
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
ssl_dhparam /etc/v2ray/dhparam.pem; # (TLSv1.2 可选) 防止中间人攻击
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always; # (可选) 传输头
# 网站位置
location / {
root /path/to/site/_site;
index index.html;
}
}
自动同步服务器上的网页
创建自动同步脚本
- 创建 shell 脚本
$ nano /home/sync.sh
- 写入脚本内容
#!/bin/bash
cd /path/to/site
git pull
JEKYLL_ENV=production /usr/local/bin/jekyll build
- 更改脚本权限
$ sudo chmod +x /home/sync.sh
crontab 定时任务
设置 crontab 定时任务, 每天从 master 分支拉取更新 详见: crontab 定时任务
- 打开 crontab 的设置页面
crontab -e
- 每日定时更新页面
写入以下信息(每日0点0分启动同步脚本, 且不产生日志), 写入后 Ctrl + S 保存, Ctrl + X 退出.
0 0 * * * /home/sync.sh >/dev/null 2>&1
- 重载 crontab 配置
$sudo /etc/init.d/cron reload
至此你的服务器上的网页就搭建完成了, 且只要从本地端修改 push 至 GitHub, 你的服务器也会自动完成更新.