1. 环境说明

  • 操作系统:Linux
  • 已安装 Docker
  • Markdown 文档路径:/root/md/
  • 部署后访问地址:http://<服务器IP>/

整体思路:

  1. 把散落的 Markdown 文档汇集成一个标准的 MkDocs 项目;
  2. 用一次性容器(--rm)执行 mkdocs build,产出纯静态文件到 site/;
  3. 用常驻的 Nginx 容器以只读方式挂载 site/ 对外提供服务。

这样做的好处是:构建环境(Python + MkDocs + 主题)完全封装在镜像里,宿主机上不需要安装任何 Python 依赖;运行时只有一个极小的 nginx:alpine 容器。

1.1 相关文件路径

路径 说明
/root/md/ Markdown 源文档目录
/root/mkdocs-project/ MkDocs 项目目录
/root/mkdocs-project/docs/ 复制后的文档目录
/root/mkdocs-project/mkdocs.yml MkDocs 配置文件
/root/mkdocs-project/site/ 生成的静态站点目录

2. 镜像选择与 Dockerfile

2.1 直接使用官方镜像(推荐)

本案例使用官方的 Material 主题镜像 squidfunk/mkdocs-material,它已内置:

  • MkDocs 本体
  • Material for MkDocs 主题
  • 常用的 pymdownx 系列 Markdown 扩展

镜像约定:容器内的 /docs 是项目工作目录(即放 mkdocs.yml 的那一层),所以挂载时把宿主机项目根目录挂到 /docs。

docker pull squidfunk/mkdocs-material

2.2 需要额外插件时自建镜像(可选)

如果 mkdocs.yml 中用到了官方镜像未内置的插件(例如 awesome-pages、mkdocs-git-revision-date-localized-plugin 等),直接构建会报插件未安装的错误(见"常见问题")。此时可以在官方镜像基础上写一个 Dockerfile 扩展:

FROM squidfunk/mkdocs-material

# 按需安装额外的 MkDocs 插件
RUN pip install --no-cache-dir \
      mkdocs-awesome-pages-plugin \
      mkdocs-git-revision-date-localized-plugin

WORKDIR /docs

构建自定义镜像:

cd /root/mkdocs-project
docker build -t my-mkdocs:latest .

后续所有 docker run ... squidfunk/mkdocs-material 命令都可以替换为 docker run ... my-mkdocs:latest。

如果不需要额外插件,跳过本节,直接使用官方镜像即可。


3. 准备项目结构与 mkdocs.yml 配置

3.1 准备 MkDocs 项目结构

mkdir -p /root/mkdocs-project/docs
cp -r /root/md/* /root/mkdocs-project/docs/

3.2 创建 MkDocs 配置文件

在 /root/mkdocs-project/mkdocs.yml 中写入基础配置:

site_name: 技术文档
site_description: Linux 运维技术文档
site_author: BOSS
theme:
  name: material
  language: zh
  palette:
    - scheme: default
      primary: indigo
      accent: indigo
      toggle:
        icon: material/brightness-7
        name: 切换到深色模式
    - scheme: slate
      primary: indigo
      accent: indigo
      toggle:
        icon: material/brightness-4
        name: 切换到浅色模式
  features:
    - navigation.tabs
    - navigation.sections
    - navigation.expand
    - search.suggest
    - search.highlight
plugins:
  - search
markdown_extensions:
  - pymdownx.highlight:
      anchor_linenums: true
  - pymdownx.inlinehilite
  - pymdownx.snippets
  - pymdownx.superfences
  - tables
  - fenced_code
  - toc:
      permalink: true

配置要点:

  • theme.language: zh 让主题界面(搜索框、上一页/下一页等)显示中文。
  • palette 配置了两套配色并带 toggle,页面上会出现浅色/深色模式切换按钮。
  • plugins 只保留 search,避免依赖官方镜像未内置的插件。
  • markdown_extensions 中的 pymdownx.* 提供代码高亮、代码块嵌套等能力,toc.permalink: true 给每个标题生成锚点链接。

3.3 生成导航配置

根据 /root/md/ 下的目录结构自动生成 nav 导航和首页 index.md。

示例导航结构:

nav:
  - 首页: index.md
  - 第一阶段:
      - 01-Linux基础操作: 第一阶段/01-Linux基础操作.md
      - 02-用户与权限管理: 第二阶段/02-用户与权限管理.md
      - ...
  - 第二阶段:
      - Apache-Web服务器: 第二阶段/Apache-Web服务器.md
      - ...
  - 第三阶段:
      - 01-Tomcat与JavaWeb部署: 第三阶段/01-Tomcat与JavaWeb部署.md
      - ...
  - 其他:
      - CentOS7添加Win7引导: 其他/CentOS7添加Win7引导.md

nav 中的路径都是相对 docs/ 目录的相对路径。文档很多时可以用脚本按目录结构自动生成这段 YAML,避免手工维护出错。


4. 容器构建与运行、端口映射

4.1 生成静态站点

cd /root/mkdocs-project
docker run --rm -v /root/mkdocs-project:/docs squidfunk/mkdocs-material build

生成后的静态文件位于 /root/mkdocs-project/site/。

参数说明:

参数 含义
--rm 容器执行完自动删除,不留垃圾容器
-v /root/mkdocs-project:/docs 把项目目录挂载到镜像约定的工作目录 /docs
build 传给镜像入口的子命令,即执行 mkdocs build

4.2 启动 nginx 容器

docker rm -f nginx-docs 2>/dev/null

docker run -d \
  --name nginx-docs \
  -p 80:80 \
  -v /root/mkdocs-project/site:/usr/share/nginx/html:ro \
  nginx:alpine

参数说明:

参数 含义
docker rm -f nginx-docs 2>/dev/null 先强制删除同名旧容器,保证命令可反复执行;容器不存在时忽略报错
-d 后台运行
-p 80:80 端口映射,宿主机 80 → 容器 80
-v .../site:/usr/share/nginx/html:ro 把静态站点目录以只读(ro)方式挂载到 Nginx 默认站点根目录
nginx:alpine 体积极小的 Nginx 镜像

4.3 验证访问

docker ps --filter name=nginx-docs --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost/

正常应返回 HTTP 200。

浏览器访问 http://<服务器IP>/ 即可看到文档站点。


5. 文档目录挂载与更新

5.1 更新文档后重新生成站点

如果 /root/md/ 目录下的文档有更新,执行以下命令重新生成站点:

# 重新复制文档
cp -r /root/md/* /root/mkdocs-project/docs/

# 重新生成静态站点
cd /root/mkdocs-project
docker run --rm -v /root/mkdocs-project:/docs squidfunk/mkdocs-material build

注意:如果新增了目录或文件结构发生变化,需要同步更新 mkdocs.yml 中的 nav 配置。

nginx 容器挂载的是 site/ 目录,站点更新后无需重启 nginx 容器。

这是挂载方式带来的关键好处:Nginx 直接读宿主机目录,site/ 内容一变,下一次请求就是新内容,无需 docker restart。

5.2 编写文档时的热更新(可选)

正式发布用 build,而在编写、调试阶段可以用 MkDocs 自带的开发服务器,它带文件监听与自动刷新(热更新):

docker run --rm -it \
  -p 8000:8000 \
  -v /root/mkdocs-project:/docs \
  squidfunk/mkdocs-material serve --dev-addr=0.0.0.0:8000

说明:

  • serve 子命令启动开发服务器,修改 docs/ 下的 Markdown 后浏览器会自动刷新。
  • 必须加 --dev-addr=0.0.0.0:8000,否则默认只监听容器内的 127.0.0.1,宿主机访问不到。
  • 访问 http://<服务器IP>:8000/。
  • 开发服务器仅用于本地预览,性能与安全性都不适合对外提供服务,正式环境仍应使用"build + Nginx 托管"的方式。

6. 常见问题

6.1 awesome-pages 插件未安装

如果配置中使用了 awesome-pages 插件但镜像未安装,会出现如下错误:

ERROR - Config value 'plugins': The "awesome-pages" plugin is not installed

解决方法:从 mkdocs.yml 的 plugins 中移除 awesome-pages,只保留 search。

若确实需要该插件,则按"2.2 需要额外插件时自建镜像"用 Dockerfile 安装后再构建。

6.2 文档内锚点链接警告

生成时可能出现类似警告:

INFO - Doc file '第一阶段/DNS服务部署.md' contains a link '#1-域名与-dns-基础', but there is no such anchor on this page.

这类警告不影响站点生成和展示,只是提示文档内部的锚点链接可能失效。如需修复,可在 Markdown 文件中补充对应标题。

6.3 端口被占用

如果 80 端口已被占用,启动 nginx 容器会失败。可将映射端口改为其他端口,例如:

docker run -d \
  --name nginx-docs \
  -p 8080:80 \
  -v /root/mkdocs-project/site:/usr/share/nginx/html:ro \
  nginx:alpine

然后访问 http://<服务器IP>:8080/。


最后修改:2026 年 09 月 20 日
如果觉得我的文章对你有用,请随意赞赏