Linux命令在线手册私有化部署实战:内网Nginx与Docker方案
如果你的工作环境里还有一台常年连不上外网的服务器,或者你带着团队想在内部搞一个统一的技术手册入口,那 linux-command 这个开源项目绝对值得你花十分钟部署一下。简单说,它把 Linux 常用命令整理成了一个带搜索、带分类、带中文说明的在线手册,GitHub 上那个 jaywcjlove/linux-command 项目就是它。你能直接用它自带的静态页面,也可以把它私有化部署到自己的服务器上,完全避开外部网络依赖。这篇我就从实战角度聊聊,为什么要私有化、怎么选方案、具体怎么一步步跑起来,以及我踩过的几个坑。
1. 为什么非要把 linux-command 私有化部署不可
先说清楚一个前提:这个项目本身已经提供了在线访问的方式,很多人直接用 GitHub Pages 上面的页面也能查命令。那为什么还要自己部署一套?如果你只在自己电脑上偶尔查一下,确实没必要折腾。但凡你处在这几种场景之一,私有化的价值就会很明显。
1.1 一个命令查询工具,为什么要自己扛一台服务
第一个真实需求是内网隔离。很多开发、测试、运维环境是物理隔离或半隔离的,生产网段根本访问不了外网。这时候开发者想查一个 tar 的完整参数,或者确认 rsync 排除目录的写法,总不能靠记忆硬撑,更不能把公司资料往外部网页里贴。把 linux-command 放到内网,等于在内部建了一个「命令字典」。
第二个需求是团队共享。我自己在的公司里,新人入职前两周最大的痛点不是写代码,而是 Linux 命令不熟。给一份 PDF 手册,更新麻烦还不方便搜;给一个外网链接,又有人反馈打不开。后来我把 linux-command 部署到一台内部服务器上,新人培训时直接给一个地址,搜索、复制、对照说明,效率高非常多。这东西一个人用是工具,全组用就成了基础设施。
第三个需求是可控和扩展。私有化部署之后,页面内容、访问方式、是否加认证、是否嵌入公司 Wiki,全部由你自己决定。你可以把团队内部的常用脚本、踩坑笔记做成新的页面放进去,甚至把整个文档服务反代到公司域名下,形成一个内部的「技术小百科」。这是直接用公共页面做不到的。
1.2 私有化部署解决的三个真实痛点
对照我实际接触到的团队情况,部署这套东西解决的无非是下面三类问题:
- 网络不可达问题。外网访问受限的机房、云上内网环境、防火墙策略严格的企业办公网,这是最普遍的原因。
- 数据安全与合规问题。虽然命令手册本身没有机密信息,但概念上你是在「把内部技术资产放到外部平台」的边缘试探。对于有合规要求的团队,内部系统一律走内网部署是默认原则。
- 可用性与速度问题。外网公共页面受对方服务器状态和本地出口带宽影响。内网部署后,加载基本是秒开,而且不受上游项目变更影响,你锁定的版本就是锁定了。
搞清楚这些动机,你就知道后面部署时该往哪个方向用力了:不是为了炫技术,而是为了在一个受限环境里提供稳定、快速、可控的服务。
2. 动手前的准备与方案选型
部署之前先盘一下手上有什么。linux-command 这个项目有个很好的特性:它的核心产物是静态页面,没有后端服务、没有数据库、没有运行时依赖。这意味着你对部署环境的要求低到令人发指。一台 1 核 1G 的小机器,甚至 512M 内存都跑得动;磁盘占用也就几十到一百多 MB。如果手头连一台 Linux 机器都没有,Windows 上的 WSL 也能临时跑。
2.1 部署前需要准备什么
硬件和系统方面,准备一台 CentOS/Rocky、Ubuntu/Debian 或其他主流发行版的服务器或虚拟机即可。需要能执行基础命令的权限,尽量拿 sudo 或 root。网络方面,确定你希望服务监听哪个端口。默认大家都喜欢用 80 或 8080;如果机器上已经有 Nginx,直接复用 80 端口加一个 server 块就行。
软件方面,按方案不同准备的东西也不同:
- 如果走静态托管,需要装一个 Web 服务器,常见选择是 Nginx,或者用更轻量的 Caddy。
- 如果走容器化,需要 Docker Engine,或已有 Kubernetes 集群。
- 如果只是个人临时用,Python 的
http.server都能撑起来,但不建议这么干,没有优化也没有守护进程。
准备好 git,用于拉取项目和后续更新。如果内网真的完全离线,也可以拿一台有网的机器 git clone 后打包拷贝进去,后面我会在离线场景里详细说。
2.2 三种部署方式的取舍
我在实际部署和帮同事搭建时试过几种方式,做了一张对比表,看完你对选型大概就有数了。
| 部署方式 | 适合场景 | 资源占用 | 维护成本 | 推荐程度 |
|---|---|---|---|---|
| Nginx/Caddy 静态托管 | 小团队、个人、内网 | 极低 | 低 | 推荐 |
| Docker / Compose | 已有容器环境、统一管理 | 低,多一层进程 | 低 | 比较推荐 |
| 挂到现有 Wiki/文档平台 | 已有知识库系统 | 看平台 | 较低 | 看情况 |
我个人最推荐的是 Nginx 静态托管。理由很简单:项目本身就是纯静态文件,用 Nginx 直接指向 docs 目录就够了,少了一层容器反而少了一个故障点和镜像拉取问题。如果你公司已经把容器化当标准交付方式,那用 Docker 也很合适,毕竟跟 k8s 里的其他服务统一管理,运维上反而省事。如果团队本来就有 Wiki 系统,比如 Confluence 之类的,甚至可以把 linux-command 的页面嵌进去或单独开一个空间,但这需要看 Wiki 服务是否支持直接托管静态资源,多一步定制成本。
除了方式本身,还有两个容易忽略的选型点:
- 是否要加访问认证。纯内网工具我建议先不加,降低使用门槛;但如果公司对访问审计有要求,就在 Nginx 前面加一层 Basic Auth 或接入统一的 SSO,这个后面会讲。
- 是否要配 HTTPS。内网环境很多人嫌麻烦不配,但我建议至少把证书装上,哪怕用自签名,因为浏览器对 HTTP 访问的密码管理和剪贴板功能限制越来越多,迟早要切。
3. 实操部署:从拉取代码到对外访问
接下来是重头戏,我直接按我在服务器上操作的顺序来写,复制粘贴就能用。我以 Ubuntu 22.04 + Nginx 为默认环境,如果你用的是 CentOS 系列,把 apt 换成 yum/dnf 就行。
3.1 获取 linux-command 项目并理解目录结构
先选择一个合适的部署目录,通常放在 /opt 或 /usr/local/share 下面,方便和系统文件隔离。
克隆完成后,进入项目看一眼目录结构:
里面你会看到 docs 目录,这就是最终的静态站点根目录。项目把大量 Linux 命令整理成了带目录、带索引的静态页面,所有搜索、分类跳转都通过前端 JS 完成,不依赖后端接口。看到 docs,整个部署思路就清晰了:Web 服务器把根目录指到这里,让用户访问 index.html,剩下的交给浏览器。
3.2 方案一:Nginx 静态托管(推荐)
安装 Nginx:
然后创建一个针对 linux-command 的站点配置。我习惯在 /etc/nginx/conf.d/ 下单独放一个文件,比如 linux-command.conf:
说明几个点:
server_name在内网环境可以是 IP 或内部域名。如果是 IP 访问,直接写 IP 或留空,Nginx 默认会把匹配不到 server_name 的请求落到这个 server 块。try_files是为了让静态资源路径都能正确映射到文件,避免出现 404。- 加
gzip是因为页面里 JS 和 CSS 文件体积不小,压缩后加载速度体感差别很大。
配置写完后检查一下语法并重载:
然后把访问机器的浏览器指向 http://<你的服务器IP>,如果看到 linux-command 的界面并能搜索命令,基本就成功了。
3.3 方案二:Docker 容器化部署
如果你所在的团队已经有 Docker 标准,想把这套服务纳入容器管理,方法也很直接。官方并没有维护一个专门的 linux-command 镜像,所以我们随手用 Nginx 官方镜像包一层即可:
这里解释一下每个参数的作用:
--name linux-command给容器起名,方便docker logs、docker exec定位。-p 8080:80把宿主机 8080 端口映射到容器内 Nginx 的 80 端口。如果宿主机 80 空闲,也可以改成-p 80:80。-v /opt/linux-command/docs:/usr/share/nginx/html:ro把项目里的docs目录挂载到 Nginx 默认站点目录,:ro表示只读,避免容器内误修改宿主机文件。--restart always让容器在服务器重启或进程崩溃后自动拉起,省心。
如果你习惯用 docker-compose,创建一个 docker-compose.yml:
然后 docker compose up -d 即可。这种方式的优点是你后续如果想让服务自动更新,只需更新宿主机目录里的文件,容器内不用动,因为挂载是实时的。
3.4 配域名、上 HTTPS、加内网 DNS
部署成功后,我建议顺手把域名解析和 HTTPS 搞定,别等团队用起来了再折腾。
先讲域名。如果公司内网有 DNS 服务器,加一条 A 记录指向你的服务器 IP,比如 linux-command.internal.company.com。没有 DNS,就让同事直接访问 IP,也问题不大。但我强烈建议至少在 Nginx 里配好 server_name,以后切域名不用改代码。
再讲 HTTPS。内网环境没有公开域名,用 Certbot 申请证书可能不太方便,有两个实用思路:
- 如果你能拿到一个公网域名且能通过
HTTP-01验证,用 Caddy 做反向代理最简单,它自动申请和续期证书。Caddy 配置比 Nginx 更简洁:
Caddy 会自动处理 HTTPS 证书,几乎零成本。缺点是你要保证该域名能正常被外网或内网 DNS 正确解析到这台机器,并且 80/443 端口出得去。
- 如果纯内网且没有合理证书路径,用自签名证书。Nginx 里开启 SSL,然后让同事把证书导入到信任库。这一步有点繁琐,但一劳永逸。
3.5 让命令库自动保持最新
linux-command 的上游项目更新频率虽然不算夸张,但隔一段时间就会补充新命令和修复说明。手动 git pull 很容易忘,我一般用 cron 定时自动化。
先写一个简单的更新脚本 /opt/update-linux-command.sh:
加执行权限:
然后用 crontab -e 加入定时任务,比如每天凌晨 3 点检查一次:
这里要提醒一句:如果走 Docker 挂载,更新完宿主机目录后容器里的内容也自动更新,因为挂载是实时的;如果走 Nginx 静态托管,同样不需要重启 Nginx。唯一的例外是页面里的 JS 或 CSS 文件名带 hash,老用户浏览器可能缓存旧文件,所以我建议在 Nginx 里给静态资源配置一个合理的 Cache-Control,既能加速访问,又能在更新后通过刷新解决。
4. 常见问题与排查技巧实录
这套服务主体是静态页面,按理说不会出太大问题,但实际部署时小坑一个接一个。我把自己遇到过和帮别人处理过的高频问题列一下,每一类都给出了排查思路。
4.1 端口、权限、防火墙三座大山
端口被占用
如果你设置 Nginx 监听 80,启动时发现已经在用,最常见的原因是服务器上已经跑了一个 Nginx 或其他 Web 服务。排查命令:
拿到占用进程后,要么把这个服务迁移走,要么让 linux-command 换一个端口。换端口的做法是改 listen 行重新加载,简单粗暴但有效。
目录权限导致 403
Nginx 以 www-data 用户运行,如果你用普通用户 clone 到 /opt/linux-command,目录拥有者可能是当前用户。默认情况下 www-data 读不到其他用户目录下的文件,表现出来就是访问首页返回 403。解决办法是把目录所有人调整为 www-data,或者给 others 加读和执行权限:
注意不要给写权限,静态站点只需要可读。
防火墙没放行
Ubuntu 上默认的 ufw 或云服务器安全组策略很容易让人翻车。服务在本机能 curl 通,但其他机器访问不了,十有八九就是防火墙拦截了。放行命令:
如果是 CentOS/Rocky 的 firewalld:
云主机记得还要去控制台的安全组规则里确认端口已放行,这一条经常被忽略。
4.2 更新与缓存问题
git pull 失败导致页面错乱
如果你在定时更新时用了 git pull,而本地有人手动改过文件(比如改了索引页),就可能出现冲突,导致更新的内容没有正确合入。我在实际环境里为了避免这种状况,会用 git pull --ff-only,一旦发现需要合并就直接停下,检查后手动处理。因为我们的目的是拉取上游最新内容,不需要本地保留额外修改。
页面更新后还是旧内容
这基本上是浏览器缓存。Nginx 默认会对静态资源返回弱缓存头,用户刷新很快就好。如果团队里反映强烈,可以在配置里把 index.html 的缓存时间调成 no-cache,把有 hash 的 JS/CSS 设置成长时间缓存。这种组合是前端静态部署的标配。
搜索不可用
linux-command 的搜索是纯前端实现,依赖项目里的索引数据文件。如果你部署后界面正常、分类能打开,唯独搜索没结果,优先检查 docs 目录下的数据文件是否完整,尤其是 clone 不完整或用了 --depth 1 浅克隆时可能缺历史版本文件。解决方式是重新 git pull 或完整克隆一次。
4.3 离线环境和内网隔离场景怎么处理
有些网络环境严格到连 GitHub 都连不上,这时候你没法直接在服务器上 git clone。我处理过几次,流程是:
在一台能访问外网的机器上执行完整克隆并打包:
然后把 tar 包通过跳板机、U 盘或公司内网传输通道拷贝到目标服务器:
后续的 Nginx 或 Docker 部署步骤完全相同。注意一点:离线环境后续没法自动更新,所以建议定期在有网环境重新打包再传一次,或者把内网更新流程做成名义上是手动的「半自动」,避免产生版本漂移。这种事我在实际项目里遇到过,打过包的同事离职后没人维护,半年后内网命令库明显落后于团队实际使用的命令版本,最终花了半天重新梳理。
5. 从一个命令手册到一个内部工具平台
部署完成不是终点。很多人把这个工具搭起来后只当书签用,我觉得有点浪费。它完全可以作为团队内部技术平台的入口之一,甚至和其他私有化工具组合起来形成一个小生态。
5.1 linux-command 可以和哪些工具组合
我见过几个比较顺手的组合方式:
- linux-command + 团队 Wiki/Wiki.js/Outline。把 linux-command 通过 iframe 嵌到文档平台的导航里,或者在 wiki 里把常用命令速查表链接到内部实例。对于新人培训,这比晒一堆 PDF 有效得多。
- linux-command + 私有化 Git 仓库。很多企业会搭 Gitea 或 GitLab,可以把 linux-command 的静态目录单独建一个仓库,走 GitOps 流程发布,更新记录、回滚都方便。
- linux-command + 内部搜索/导航页。团队自己开发的主页里加一个入口卡片,点开就是命令手册。看似简单,实际上让工具的曝光率和使用率大幅提升。
除了直接组合,更重要的是利用它沉淀团队自己的命令经验。比如你们项目里常用某个冷门命令组合,我一般建议直接在 docs 目录里新增一个页面,把命令说明、参数解读、团队的实际案例写进去。这样团队的知识不是散落在聊天记录里,而是沉淀在一个所有人都会访问的地方。
5.2 影响范围:从个人效率到团队基建
客观评价一下这套部署的影响范围。对个人来说,省去了背命令的记忆负担,查询成本从「打开外网页面」变成「内网秒开」,断网也能查;对团队来说,新人有入口、运维有对照、交付有标准;对组织来说,技术资产被内聚沉淀,不依赖外部网站,符合数据可控的原则。
我常把 linux-command 的私有化部署比作给团队修了一个「离线版的中文命令图书馆」。书本身不厚,但它放在内网、随时可查、开放给所有人之后,价值就远超一份被遗忘的 PDF。
6. 部署时的几个额外提醒
最后补充一些零散但很重要的经验,这些通常不会写在官方 README 里。
- 访问日志要留着。Nginx 默认会给
/var/log/nginx写访问日志。内网工具流量不大,但也别随手全关,至少留一段时间,方便哪天出了异常排查是谁在访问、访问了什么。 - 备份非常简单。整个站点就是
/opt/linux-command一个目录,备份只需打包。我一般做系统备份时会顺带把这个目录纳入,恢复时几秒钟完成。 - 不要为了性能做花哨的 CDN。内网场景下,Nginx 直接吐静态文件性能已经足够,加内存缓存、上 Redis 都属于画蛇添足。
- 如果公司内部对开源协议有要求,确认一下 linux-command 的许可证。它的开源协议允许自由使用和修改,按项目说明保留相关声明即可。私有化部署本身完全不构成问题。
我在实际运维中还有一个小技巧:把部署过程本身也文档化,放在团队 wiki 里。这样下一个接手的人不用重新摸索「当时怎么配的 Nginx」「更新脚本在哪」。部署一个小工具本身不难,但让它的维护经验能在团队里传下去,才算真正把这件事做完整了。
如果你现在正好有一台空闲内网机器,花十五分钟把 linux-command 跑起来,然后拉两个同事试用一下。等他们开始主动问你要链接的时候,你就知道这件事做对了。