跳转至

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:8000http://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.ymlnav 中,如果该部分空缺,将通过发现文档目录中的所有 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),后期定制时才用得到,故略。