应用文档

过去,我们开发一个标准 api 并提供服务,接口文档和系统对接文档多是通过线下沟通完成,过程中提供的文档格式、版本混乱并且无法进行版本管理。 为了更好的管理各个服务提供的系统能力,我们计划对外提供一个统一的开放平台文档给我们所有的对接方。以便达到一下目标:

  1. 系统文档在线化,各个系统的文档可以通过网页访问。不在依赖于线下文档。

  2. 文档可基于 Git 版本管理,方便查看历史版本。

小技巧

本文档即使用以下方法编辑、生成、发布。

文档编写及工程化

文档使用开源工具 readthedocs 生成,并使用 markdown 编写。

  1. 安装依赖工具, (工具主要依赖 python3,windows 平台请参考此文章安装)

    # 安装组件
    apt install git
    apt install make
    apt install python3
    apt install python3-pip
    pip3 install -U Sphinx
    pip3 install sphinx-autobuild
    pip3 install sphinx_rtd_theme
    pip3 install myst-parser
    
  2. 组件安装完成后,执行脚手架生产初始化文件

    # 新建文件夹
    mkdir doc
    # 脚手架生成初始文件
    sphinx-quickstart
    # 编译,生成文档
    make html
    # 预览文档
    open build/html/index.html
    
  3. 修改 conf.py 文件 & 增加 css 样式文件

    doc/source/_static/ 文件夹增加style.css

    .wy-nav-content {
        max-width: 1024px !important;
    }
    
    # conf.py 示例内容
    import recommonmark
    from recommonmark.transform import AutoStructify
    
    project = '技术文档'
    copyright = '2021-Y%, Seazen'
    author = 'Seazen'
    
    extensions = [ 'myst_parser' ]
    source_suffix = ['.rst', '.md']
    templates_path = ['_templates']
    language = 'zh_CN'
    exclude_patterns = []
    html_theme = 'sphinx_rtd_theme'
    html_show_sphinx = False
    html_show_sourcelink = False
    html_static_path = ['_static']
    
    def setup(app):
        app.add_css_file('style.css')
    
  4. 组织文档结构。

    source 文件夹中添加 markdown 文件,并编写文档。 在 index.rst 添加如下内容调整文档左边导航显示的排列顺序。

    服务文档
    ==================================
    
    .. toctree::
       :maxdepth: 2
       :caption: 目录:
    
       Preface.md
       API.md
    
  5. 增加 build-docs.sh 构造生成文档脚本

    我们通过在 jenkins 构造时使用 shell 脚本将文档编译,并复制到固定目录。然后文档服务,读取固定目录文件并加载成 web 页面。
    Jenkinsfile 文件的同级目录增加 build-docs.sh

    # 编译文档,循环当前目录子目录中包含 Makefile 的文件,编译,并将编译结果复制到固定的 /tmp/docs-dist/ 目录中
    for d in */ ; do
        if [ -f "$d/Makefile" ]; then
            cd $d && make html && cd ../
            source="$d/build/html/*"
            dist="/tmp/docs-dist/$d"
            rm -rf $dist && mkdir -p $dist && cp -R $source $dist && rm -rf "$d/build"
        fi
    done
    
  6. 增加 Dockerfile

    FROM node:14.21.3
    WORKDIR /tmp
    COPY . /tmp
    RUN bash build-docs.sh
    CMD ["sleep","10000"]
    
  7. 修改 Jenkinsfile 文件

    // ...
    stage('dotnet publish') {
        dir('src/Seazen.Docs') {
            container('jnlp') {
                withDockerRegistry([credentialsId: 'uuid', url: 'https://seazen.tencentcloudcr.com']) {
                    def image = docker.build("docs:laster","-f Dockerfile ./")
                    // 将构造服务器上的 /mnt/docs 文件夹挂载到容器中,用于将容器中编译的结果复制到物理磁盘中。
                    image.inside('-v /mnt/docs:/mnt/docs -u root') {
                        sh 'cp -r /tmp/docs-dist/* /mnt/docs/'
                        sh 'chown -R 65534:65534 /mnt/docs/'
                    }
                }
            }
    
            // 清理编译服务器上镜像
            sh 'sleep 5 && docker image rm docs:laster'
        }
    }
    // ...
    

    注意

    /mnt/docs/ 这个文件夹,是通过在 jenkins 构造的 Pod 上挂在上去的 nfs 共享文件夹。

  8. 部署文档服务

    小技巧

    可以使用任意 web 服务器,将编译后的文档文件夹挂载到容器中。

    docker run -d -p 443:443 -v /mnt/docs:/usr/share/nginx/html nginx