MkDocs 简单部署
MkDocs 是一个快速、简单且非常华丽的静态站点生成器,用于构建项目文档。文档源文件采用 Markdown 编写,只需要单个 YAML 配置文件进行配置,另外还有第三方主题和插件可以进行扩展。
MkDocs 官网:https://www.mkdocs.org
1. 快速入门
MkDocs 基于 Python 编写,也贯彻了 Python 里“简洁胜于复杂”的理念,与其他常见的静态网站生成器相比,无需繁琐的环境配置。以下入门安装步骤非常简单,操作时间应该不会超过本章的阅读时间。
1.1. 准备 Python 和 pip
MkDocs 需要最新版本的 Python 和 Python 包管理器 pip。使用以下命令(查询程序版本)来检查是否已经安装了这些软件:
python --version #或者 python3 --version
pip --version #或者 pip3 --version
pip install --upgrade pip #将 pip 升级到最新
Debian11 系统自带 Python3.9,无需安装。如果出现 python: command not found
,使用 python3 --version
即可显示版本。此时可能需要创建软链接,使用 ln 命令将 /usr/bin/python3.9 指向 /usr/bin/python ,即 sudo ln -s /usr/bin/python3.9 /usr/bin/python
。
如果是在 Windows 系统下,建议通过 Anaconda 安装,较为简便。如果不使用 Python 进行编程,只是为了 MkDocs,直接去 Python 官网下载安装包就好。务必将 Python 添加到 PATH 中,如果忘记了,最新版本的 Python 中包含一个执行此操作的脚本。到 Python 安装目录(例如 C:\Python39)——Tools—— Scripts,运行 win_add2path.py。或者下载此脚本并运行。
如果是第一次安装 pip,下载 get-pip.py,然后运行命令 python get-pip.py
进行安装。
1.2. 安装并查验 MkDocs
Mkdocs 使用 pip 安装包:
pip install mkdocs
查验安装是否成功:
mkdocs --version
如果使用 Windows 系统,则上述某些命令可能无法实现开箱即用,可在每个Python 命令前加上 python -m
这样的前缀。
如果使用 material 主题,直接运行 pip install mkdocs-material
将自动安装所有依赖包的兼容版本(MkDocs,Markdown,Pygments 和 pymdown-extensions),无需单独安装这些软件包。
1.3. 初始化项目
转到项目所在目录并输入:
mkdocs new .
或者将命令中的 .
替换成需要新建的目录。该命令将创建以下结构:
├─ docs/
│ └─ index.md
└─ mkdocs.yml
这里 mkdocs.yml 是配置文件, docs 是包含所有文档源文件的文件夹( docs 是 docs_dir 配置设置的默认值),现在只有一个示例文件 index.md。
1.4. 边写边预览
MkDocs 带有一个内置的开发服务器,可在处理文档时预览文档。确保与 mkdocs.yml 配置文件位于同一目录中,然后通过运行命令启动服务器:
mkdocs serve
然后在浏览器中打开 http://127.0.0.1:8000 或 http://localhost:8000,您将看到正在显示的默认主页。
开发服务器还支持自动重新加载,并且只要配置文件、文档目录或主题目录中的任何内容发生更改,就会重新构建文档。
下面是一些简单修改的例子:
- 修改 docs/index.md 标题,在文本编辑器中打开,将初始标题更改为 MkLorum,然后保存更改。
- 修改 mkdocs.yml 的必选项,只有两个必需选项 site_name 和 site_url。比如将 site_name 设置为 MkLorum ,site_url 默认设置
https://example.com/
,改成自己的域名或 IP 地址,并保存文件。 - 添加页面。手动添加 md 文件或者命令创建
curl 'https://jaspervdj.be/lorem-markdownum/markdown.txt' > docs/about.md
,然后修改配置文件并通过添加 nav 设置,在导航标题中添加有关每个页面的顺序、标题和嵌套的一些信息。 - 修改 Favicon 图标。要使用不同的图标,在 docs 中建立子目录 img,把自定义文件 favicon.ico 复制过去。MkDocs 将自动检测并使用该文件。
上述修改后的配置文件示例:
site_name: MkLorum
site_url: http://192.168.1.8
nav:
- Home: index.md
- About: about.md
theme: readthedocs
如果想使用非标准 8000 端口,指定端口的启动命令为:mkdocs serve -a 0.0.0.0:8765
。
1.5. 生成静态网站并托管
构建静态网站的命令
mkdocs build
这将创建一个名为 site
的新目录,源文档已输出为 HTML 文件,图片等各种其他媒体作为文档主题的一部分也复制到目录中,甚至还有一个网站地图 sitemap.xml
和全文搜索索引 mkdocs/search_index.json
。
静态文件可以从任何地方托管它(VPS、虚拟主机、GitHub等),只需将整个 site 目录的内容上传即可。
有关命令的完整列表, mkdocs --help
。要查看给定命令的可用选项列表,mkdocs build --help
。
1.6. 进程守护与域名反代
通常来说,本地边写边预览就够用了,网站彻底做好后再统一上传服务器。而且,静态网站的好处是系统资源耗费非常少,对硬件要求比较低。但是呢,每次小修改都要重新生成和上传,仪式感过于强烈了一些些。
所以,在内容较少且更新频繁的建站初期,我还是选择在云服务器上,边写边预览,预览即发布。在腾讯云轻量服务器(2C4G8M)上实测,16MB 的 md 文件,600 卷《大般若经》,约 580 万字,打开基本没有卡顿。实际文件不可能这么大,肯定得拆分。
这就需要进程守护和域名反代,最简单的实现方法是使用宝塔面板。
安装 Supervisor 管理器来进行进程守护,名称随便起,运行目录就是项目的安装目录,命令是 mkdocs serve
。当然,也可以将命令写成 sh 脚本,通过堡塔应用管理器进行管理。
然后添加一个网站,绑定域名,先配置免费的 SSL 证书,然后创建反向代理,目标 URL 就是前面的 http://127.0.0.1:8000。
2. 详细设置
2.1. 关于 YAML
YAML 是“YAML Ain't a Markup Language”(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据为中心,而不是以标记语言为重点,而用反向缩略语重命名。
YAML 的基本语法规则:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用 Tab 键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#
表示注释,从这个字符一直到行尾,都会被解析器忽略
YAML 支持的数据结构:
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
照抄 MkDocs 官方文档中的示例已经够用了,更多内容可以参考 YAML 入门教程 、YAML 官网、YAML 维基百科。
2.2. 文档布局
源 Markdown 文件都在顶层目录 docs
下,扩展名支持 markdown、mdown、mkdn、mkd、md 等。项目主页按照惯例被命名为 index.md
,优先于同目录下的 README.md
。名称以点开头的文件(.foo.md
)或目录(.bar/baz.md
)将被忽略。
可以通过创建多个 Markdown 文件来创建多页文档,还可以将 Markdown 文件包含在嵌套目录中。所有非 Markdown 文件(图片等)将原封不动地复制到构建的站点,以供链接。
文件导航菜单在 mkdocs.yml
的 nav
中,如果该部分空缺,将通过发现文档目录中的所有 Markdown 文件自动创建导航。自动创建的导航配置将始终按文件名的字母数字顺序排序(中文是拼音字母顺序,当然 index.md
文件将始终在目录中首先列出)。如果希望其他方式排序,需要手动定义导航配置。
导航项的标题可自行定义,否则将从 Markdown 文件的内容中自动提取,如果文件中没有大标题则从文件名中推断出来。导航子部分可以通过在部分标题下一起列出相关页面来创建。例如
nav:
- Home: 'index.md'
- 'User Guide':
- 'Writing your docs': 'writing-your-docs.md'
- 'Styling your docs': 'styling-your-docs.md'
- About:
- 'License': 'license.md'
- 'Release Notes': 'release-notes.md'
需要注意,一个目录不能有分配给它的页面,只能有子页面和子目录。这一问题在Material for MkDocs 主题中,通过子目录的 index.md 的方法解决了。虽然可以随意嵌套多个,但是不要过于复杂,从而使用户难以通过站点导航进行导航。
导航配置中未列出的任何页面仍将呈现并包含在构建的站点中,只是没有全局导航,也不会包含在 previous 和 next 链接中。除非直接链接,否则此类页面将被“隐藏”。
MkDocs 使用 Python-Markdown 库将 Markdown 文档呈现为 HTML。该库只支持原生或者说基本的 Markdown 语法,所以一般需要在 mkdocs.yml
中添加相关扩展。
MkDocs 支持 YAML 和 MultiMarkdown 样式元数据。但是我之所以选择 MkDocs 而不是 Hugo ,就是不喜欢每篇文档的开头写一堆“标题”“作者”“日期”等标记,所以这部分内容直接跳过。
2.3. 默认配置选项
当然不是每一项都需要设置,按需取舍。总结为一个配置文件,如下
site_name: Marshmallow Generator #项目名称,字符串
site_url: http://192.168.1.8/foo/ #站点网址 URL,站点的根位于域名的子目录(/foo)中
repo_url: https://github.com/example/repository/ #GitHub等存储库链接
edit_uri: root/path/docs/ #从基础目录到 docs 目录的路径(各存储库要求可能不同)
site_description: #站点描述
site_author: #作者姓名
copyright: #版权信息
remote_branch: #远程分支,gh-deploy部署到 GitHub Pages 时设置,默认 gh-pages
remote_name: #远程名称,默认 origin
nav: #导航格式和布局
- Introduction: 'index.md' #指向本地文件
- 'about.md'
- 'Issue Tracker': 'https://example.com/' #指向外部站点,完整URL
- 'Bug Tracker': '/bugs/' #根在子目录中时,相对 URL
theme: #主题
name: mkdocs #主题名称
locale: en #语言环境,中文是 zh
custom_dir: my_theme_customizations/ #自定义主题目录,可相对可绝对
static_templates: #静态模板,必须位于主题模板目录或custom_dir主题配置中定义的目录中
- sitemap.html
include_sidebar: false #是否包括侧边栏
docs_dir:'docs' #文档源 Markdown 文件的目录,可相对可绝对,默认'docs'
site_dir:'site' #站点目录,可相对可绝对,默认'site'
extra_css: #主题中包含的额外 CSS 文件列表,默认为空[]
- css/extra.css
- css/second_extra.css
extra_javascript: #主题中包含的额外 JavaScript 文件列表,默认为空[]
extra_templates: #额外模板
extra: #额外的其他
version: 1.0 #显示项目版本
use_directory_urls:true #链接样式,默认true,指向目录而不是文件
strict:false #如何处理警告,true在发出警告时停止处理,false打印警告并继续处理。
dev_addr:'127.0.0.1:8000' #开发地址
markdown_extensions: #Markdown扩展列表
- smarty #启用 SmartyPants 排版扩展
- admonition #通过不同颜色现实告警、备注信息
- toc:
permalink: True #在 toc 扩展中启用永久链接
separator: "_" #分割线符号
plugins: #插件
- search #默认提供搜索,使用lunr.js作为搜索引擎
min_search_length: 2 #查询的最小长度,整数,默认3
separator: '[\s\-\.]+' #单词分隔符,默认使用空格和连字符,这里添加了点
lang:ja #搜索索引的语言,中文可使用日语
indexing: 'full' #构建索引策略,默认full索引每页的标题、章节标题和全文,sections 索引每页的标题和章节标题,titles仅索引每页的标题
- your_other_plugin #其他插件
plugins: [] #完全禁用所有插件,包括任何默认值
prebuild_index:true #生成所有页面的预建索引,大站才用,默认False,true为启用,要求安装Node.js并且命令node位于系统路径上
环境变量(Environment Variables)与配置继承(Configuration Inheritance),后期定制时才用得到,故略。