ReDoc 接口文档:NAS 上用 Docker 部署,给同事一个地址就能查 OpenAPI
作者
小编
发布时间

项目介绍
ReDoc 是一个开源的接口文档渲染器。你只要写好一份 OpenAPI 的 YAML,它就把所有接口排成一整页:左边是分组目录,点开接口,中间列每个路径参数、查询参数和请求体,右边直接给返回的 JSON 示例。
页面是静态的,不用登录,也不需要数据库。把 YAML 和编排放在 NAS 上,同事用浏览器打开一个地址就能查;接口改了,换掉 YAML,页面跟着更新,不用再发文件、翻聊天记录。
这篇用一份「家庭藏书 API」的示例 YAML 演示:四个图书接口、一个借阅接口,返回三本书。换成你自己的接口,格式照这个写就行。
项目地址:点我跳转
部署安装
只要能跑 Docker 的 NAS 都能装,下面用飞牛 NAS 演示:先用 帕斯内网穿透 拿到一个公网地址,再用 Docker Compose 把 ReDoc 装起来。装完用公网地址打开,同事在外面、用手机也能看同一页文档。
一、先用帕斯内网穿透拿到公网地址
飞牛的「应用中心」里搜 PassNAT,装上这个穿透插件,打开它,点「创建隧道」。隧道名字随便起(不超过 12 个字符),接入节点和传输协议留默认,本地 IP 留默认的 127.0.0.1,本地端口填 3652(就是下面编排里冒号左边那个端口)。
建好之后点开这条隧道,按一下电源,状态变成运行中,详情里就能看到分配好的公网地址(形如 IP:端口),先记下来。
不是飞牛的系统,PassNAT 文档的「连接使用」里有其他系统的连接教程:点我跳转。
二、准备接口说明文件
在存放编排的文件夹里新建一个文件,名字就叫 openapi.yaml,把下面这份示例整个贴进去。注意缩进是空格,不要用 Tab。
1openapi: 3.0.32info:3 title: 家庭藏书 API4 version: 1.0.05 description: |6 给家里的书架做一份接口说明:查书、看详情、登记借出。7 数据只存在 NAS 上,局域网内用浏览器打开就能看。8servers:9 - url: https://nas.local/api10 description: NAS 上的本地服务11tags:12 - name: 图书13 description: 查看和登记书架上的书14 - name: 借阅15 description: 谁把书借走了16paths:17 /books:18 get:19 tags: [图书]20 summary: 列出书架上的书21 description: 支持按书名搜索、按书柜筛选,默认一次返回 20 条。22 parameters:23 - name: q24 in: query25 description: 书名或作者关键词26 schema: { type: string }27 example: 三体28 - name: shelf29 in: query30 description: 书柜编号31 schema: { type: string }32 example: A-0333 - name: limit34 in: query35 schema: { type: integer, default: 20, maximum: 100 }36 responses:37 '200':38 description: 图书列表39 content:40 application/json:41 schema:42 type: array43 items: { $ref: '#/components/schemas/Book' }44 example:45 - id: 102446 title: 三体47 author: 刘慈欣48 shelf: A-0349 status: 在架50 - id: 102551 title: 人类简史52 author: 尤瓦尔·赫拉利53 shelf: B-0154 status: 在架55 - id: 102656 title: 设计中的设计57 author: 原研哉58 shelf: A-0359 status: 借出60 post:61 tags: [图书]62 summary: 登记一本新书63 requestBody:64 required: true65 content:66 application/json:67 schema: { $ref: '#/components/schemas/BookInput' }68 example:69 title: 置身事内70 author: 兰小欢71 shelf: C-0272 responses:73 '201':74 description: 登记成功75 content:76 application/json:77 schema: { $ref: '#/components/schemas/Book' }78 /books/{id}:79 get:80 tags: [图书]81 summary: 查看一本书的详情82 parameters:83 - name: id84 in: path85 required: true86 schema: { type: integer }87 example: 102488 responses:89 '200':90 description: 图书详情91 content:92 application/json:93 schema: { $ref: '#/components/schemas/Book' }94 '404':95 description: 没有这本书96 content:97 application/json:98 schema: { $ref: '#/components/schemas/Error' }99 delete:100 tags: [图书]101 summary: 从书架移除一本书102 parameters:103 - name: id104 in: path105 required: true106 schema: { type: integer }107 responses:108 '204':109 description: 已移除110 /books/{id}/lend:111 post:112 tags: [借阅]113 summary: 登记借出114 description: 记下借给了谁,书架上的状态会变成「借出」。115 parameters:116 - name: id117 in: path118 required: true119 schema: { type: integer }120 example: 1024121 requestBody:122 required: true123 content:124 application/json:125 schema: { $ref: '#/components/schemas/Lend' }126 example:127 borrower: 小林128 due_date: '2026-11-02'129 responses:130 '200':131 description: 借出登记成功132 content:133 application/json:134 schema: { $ref: '#/components/schemas/Book' }135components:136 schemas:137 Book:138 type: object139 description: 书架上的书140 required: [id, title, author, shelf, status]141 properties:142 id:143 type: integer144 example: 1024145 title:146 type: string147 example: 三体148 author:149 type: string150 example: 刘慈欣151 shelf:152 type: string153 description: 书柜与层号154 example: A-03155 status:156 type: string157 enum: [在架, 借出]158 example: 在架159 BookInput:160 type: object161 required: [title, author, shelf]162 properties:163 title:164 type: string165 example: 置身事内166 author:167 type: string168 example: 兰小欢169 shelf:170 type: string171 example: C-02172 Lend:173 type: object174 required: [borrower]175 properties:176 borrower:177 type: string178 description: 借书人179 example: 小林180 due_date:181 type: string182 format: date183 description: 约定归还日期184 example: '2026-11-02'185 Error:186 type: object187 properties:188 code:189 type: integer190 example: 404191 message:192 type: string193 example: 没有这本书
几个位置按自己的情况改:title 写你的服务名;description 写一两句给同事看的说明;servers 里的 https://nas.local/api 换成你的接口地址,或者直接删掉这一行;下面的 paths 和 components 换成你自己的接口。不想手写也可以先拿这份示例跑通,看到效果再改。
三、新建 Compose 项目
打开飞牛的「Docker」应用,切到「Compose」标签,点右上角的新增项目。项目名称填 redoc,路径选刚才放 openapi.yaml 的那个文件夹。来源选「创建 docker-compose.yml」,把下面这段整个贴进去:
1services:2 redoc:3 image: redocly/redoc:latest4 container_name: redoc5 restart: unless-stopped6 ports:7 - "3652:80"8 environment:9 SPEC_URL: openapi.yaml10 PAGE_TITLE: 家庭藏书 API11 volumes:12 - ./openapi.yaml:/usr/share/nginx/html/openapi.yaml:ro
这段编排要看两处:
SPEC_URL: openapi.yaml:告诉 ReDoc 去读同目录下的哪份文件。文件名改了,这里跟着改。
volumes 那一行:把宿主上的 openapi.yaml 挂进容器里 nginx 的网站目录,只读。冒号右边是容器里的路径,不要改;冒号左边是文件名,要跟 SPEC_URL 对上。
端口 3652 被占用的话,把冒号左边的数字换一个,隧道里的本地端口也跟着改。勾上「创建项目后立即启动」,镜像下完就起来了。这个镜像很小,只有几十兆,几秒钟就能拉完。
四、打开看看
用公网地址打开,先看到文档标题和简介。左边是「图书」「借阅」两组目录,点开列出接口;点 GET /books,中间是 q、shelf、limit 三个查询参数,右边是 200 返回的 JSON,三条示例数据整整齐齐。
手机上打开同一个地址,排版会自动收成一列:目录、参数和返回示例都在,不用缩放也能看。把地址发到工作群,同事点开就能查,不用登录,也不用装任何东西。
五、接口改了怎么办
改完自己的接口,把新的 openapi.yaml 覆盖上去,刷新浏览器就是新页面,容器不用重启。如果改了文件名,记得同步改编排里的 SPEC_URL 和 volumes。
接口文档跟着代码走:写接口的时候先把 YAML 写好,前端后端都照这一页来,改动也有据可查。比在聊天记录里翻「这个字段到底叫啥」省事得多。
几点说明
它只负责展示。 ReDoc 读 YAML、排版、显示示例,不提供接口本身,也不做鉴权。文档页面谁拿到地址都能看,所以别把口令、密钥写进 YAML 的示例里。
数据就是那份 YAML。 没有数据库,也没有要备份的卷。把 openapi.yaml 和 compose.yml 两个文件存好,换一台 NAS 照样能起来。
镜像标签用 latest。 升级时重新拉取镜像、重启项目即可;升级前先把两个文件备份一份,万一新版对 YAML 的要求变了,还能退回去。
和 Swagger UI 的区别。 同样是读 OpenAPI,ReDoc 更偏「读文档」:三栏排版、搜索、右侧常驻返回示例;需要在线调试接口的话,另装一个 Swagger UI 更合适。这篇只讲 ReDoc。