1. Nginx UI 项目概述与核心设计理念
1.1 项目定位与诞生背景
Nginx 的安装和基础配置并不难,真正让人头疼的是后面那些繁琐的维护操作:改一个反向代理要去翻 conf 文件,加一个静态站点要计算 location 正则,申请 SSL 证书要在服务器上敲一堆命令行,搞完之后还要记得nginx -t检查语法再 reload。一旦服务器上跑的站点多了,配置文件就是一团乱麻,每改一处都心惊胆战,生怕手一抖把整个服务搞挂。
我自己管理着几台线上服务器,高峰期跑了十几个站点和 API 服务,对这个痛点深有体会。直到我遇到 xJacky 开源的这个 Nginx UI 项目,它把 Nginx 从"命令行工具"真正变成了"可视化服务"。
Nginx UI 是一个基于 Web 的 Nginx 图形化管理平台,后端用 Go 编写,前端用 Vue 构建,整体打包后只需要运行一个二进制文件,服务器上不需要额外安装 MySQL、Redis 这些依赖,部署成本极低。它最核心的价值在于:把/etc/nginx/conf.d/下那些零散的配置文件,变成了浏览器里一张张清晰明了的表单和按钮,点一点鼠标就能完成站点的创建、启停、修改、证书配置。
这个项目适合三类人:第一类是刚入门 Nginx、对命令行不太熟悉的新手,可以通过图形界面直观理解 Nginx 的核心概念;第二类是负责多台服务器的运维工程师,用它统一管理配置、快速排查问题;第三类是自己折腾 VPS 的个人开发者,部署一次之后能省下大量重复劳动。
我第一次用它的感受是:原来通过图形界面配置 Nginx 也可以这么顺手,而且它在保留 Web 界面便捷性的同时,并没有架空底层配置本身——所有操作最终还是会落到实际的 conf 文件上,你随时可以回到命令行去看、去改,本质上它就像一个"配置生成器 + 状态监视器 + 证书管理器"三合一的工具。
1.2 核心功能架构一览
从功能模块来看,Nginx UI 做的事情可以分成五个维度:
- 配置管理:支持图形化创建和编辑 Nginx 站点配置,提供可视化表单,同时保留原始配置文件的直接编辑能力,两套模式可以随时切换。
- 状态监控:内置服务器基础指标监控面板,可以查看 CPU、内存、网络流量、Nginx 连接数和请求数等实时数据,不用再单独装 netdata 之类的工具。
- 证书管理:集成 Let's Encrypt 免费证书的申请与自动续期功能,也支持上传自定义证书,到期前会自动提醒甚至自动续签。
- 系统管理:多用户体系、用户权限控制、操作日志审计、自定义 Nginx 二进制路径等。
- 在线终端:浏览器内嵌终端工具,可以直接在页面上执行命令行操作,不需要额外开 SSH。
这五个模块合在一起,几乎覆盖了一个 Nginx 运维场景下 80% 的高频操作。下面从我的实际使用经验出发,逐个拆解这些功能的特点和隐藏细节。
2. 六大核心特点深度拆解
2.1 图形化配置:把 conf 变成可视化表单
Nginx UI 的主打功能就是简化配置。打开站点的编辑页面,你会看到它不是把 conf 原样丢给你,而是把配置项拆成了结构化的表单:域名、监听端口、根目录、索引文件、反向代理地址、缓存策略、SSL 证书下拉选择框、强制 HTTPS 跳转开关……
这种设计最直接的好处是:你再也不需要背 Nginx 的配置语法了。以前新建一个 Vue 项目的静态站点,我得写这样的配置:
server { listen 80; server_name example.com; root /var/www/example; index index.html; location / { try_files $uri $uri/ /index.html; } }这个配置本身不复杂,但如果要加 HTTPS、加 Gzip、加静态资源缓存,配置就会越堆越长,一旦写错一个分号或括号,nginx -t就会报错,新手常常被各种语法错误折磨到怀疑人生。
在 Nginx UI 里,新建站点时只需要填几个表单字段,它会自动帮你生成标准的 server 块。更重要的是,它对编辑结果有实时校验机制——每次保存前都会自动执行nginx -t来检查语法,有错误会直接提示在界面上,而不是等 reload 之后才发现线上服务挂了。
我用它创建过几个 WordPress 站点和一个 Node.js API 的反向代理,整个过程真的就像填表一样流畅。它生成的配置层次分明,注释也清楚,事后回到命令行里看文件,完全能看懂它做了什么,不会出现那种"工具生成的天书配置文件"的问题。
不过要注意一点:图形化表单覆盖的是常规场景,像自定义if语句块、复杂的 rewrite 规则、stream 模块配置这些,表单里不一定有对应的字段。这种情况下直接切到"高级模式"手工编辑反而更快。所以我的建议是——用它管理常规配置,用它辅助排查问题,但在遇到特殊需求时不要死磕表单,该上编辑器就上编辑器。
2.2 在线编辑与实时校验:双模式加成
Nginx UI 并没有因为做了图形界面就抛弃传统的文件编辑方式。在"站点编辑"页面里有两个标签页:一个是"表单/图形化"模式,一个是"配置文件"模式。
配置文件模式内置了一套带语法高亮的文本编辑器,代码补全和错误标记都能用。你可以在里面直接写原生 Nginx 配置,保存的时候它会做两件事:先检查语法,再重载配置。如果语法有问题,它会明确告诉你错误出现在哪一行、大概是哪类错误,而不是像命令行那样只丢给你一行含糊的emerg日志。
这个设计我觉得是这个项目最聪明的地方:它承认图形化表单有边界,总有高手需要直接手写 conf,所以它保留了完整的原生编辑能力,同时把"校验-重载-回滚"这套流程自动化了。
我自己的使用习惯是这样的:小站点、常规反向代理,我用表单生成;涉及 rewrite 规则、upstream 权重调整、复杂 location 嵌套的时候,我直接切到编辑器写。有了实时校验在背后撑腰,手写配置时的心理压力小了很多,反正保存之前它会告诉我错没错。
2.3 状态监控与流量统计
Nginx 自带的stub_status模块可以输出连接数等基础指标,但输出格式比较简陋,需要你在终端里定期 curl 来看,没有历史趋势,更不可能做成图表。而 Nginx UI 内置的监控面板把这个问题解决了。
它的监控页面展示的信息包括:
- 服务器基本状态:CPU 使用率、内存占用、磁盘空间、系统负载、运行时间
- Nginx 运行状态:活跃连接数、接受连接总数、处理请求总数、Reading/Writing/Waiting 连接数
- 实时图表:按时间维度绘制 CPU 和内存趋势曲线
面板的数据刷新是有延迟的,大概 3~5 秒一次,对于日常运维足够用了。想看实时吞吐的话可以在页面上直接点"刷新"按钮强制拉取最新数据。
我特别推荐在排查问题的场景里用它:比如怀疑某个站点访问变慢是不是 Nginx 连接数打满了,打开监控面板看一眼活跃连接数和 Reading 状态的趋势,再对照站点日志去定位,比之前到处敲ss、top、curl status组合命令要直观得多。
需要提醒的是,Nginx UI 的监控数据默认只存在内存里,进程重启后历史数据就没了。如果你需要长时间的监控报表,建议搭配 Prometheus + Grafana 这类专用监控栈,Nginx UI 的目标是让你"看得见问题",而不是"记录一切历史"。
2.4 SSL 证书管理自动化:告别 Let's Encrypt 手动续期
证书管理是 Nginx 场景里最麻烦的环节之一,尤其是 Let's Encrypt 证书 90 天有效期,意味着一年要手动续期四回。我见过太多人因为忘记续期,早上上班发现所有 https 站点全部证书过期,那种事故是纯粹的运维灾难。
Nginx UI 在"证书管理"模块里做了两件事:一是流程自动化,二是集中管理。
自动化部分,它内置了 Let's Encrypt 协议的客户端逻辑,你只需要在站点配置里选择启用 HTTPS,填上邮箱和一些基础参数,它会自动完成证书申请、私钥生成、Nginx 配置更新这一整套动作。到期前还能设置自动续期,快到期的证书它会提前处理续签,你只需要确保域名正确解析到服务器上、80/443 端口能正常访问验证就行。
集中管理部分,所有证书在一个页面上列出,状态一目了然:签发时间、到期时间、关联的站点、续期记录。纸质证书文件分散在磁盘各个目录的问题从此解决。
我在真实服务器上用它申请过两个域名的证书,整个流程跑通只需要几分钟。它注册 ACME 账号、签发证书、写入配置的衔接做得比较稳,没有出现那种"证书申请成功但 Nginx 没生效"的脱节问题。不过有一点经验要分享:如果你的服务器在国内、解析用的是 CDN,第一次申请证书时大概率会因为验证请求超时而失败,这种情况先把 CDN 的回源模式改成"直接回源"或者临时关闭 CDN,等证书签下来之后再恢复。
另外,付费证书、企业内部证书这类不便走 ACME 流程的场景,它支持直接上传证书文件和私钥,操作也很干脆。
2.5 多用户体系与细粒度权限控制
Nginx UI 不是单用户工具,它内置了一套用户权限系统。管理员可以创建多个用户,并为每个用户设置不同的权限级别。
角色分成管理员和普通用户。管理员拥有全部权限,可以管理用户、修改系统设置、查看日志;普通用户默认只能看到自己被授权的站点和功能。这种设计对于团队协作场景很有价值——开发团队里每个人负责不同的项目,给每个人开一个账号,只赋予他自己站点的管理权限,其他人碰不到你的配置文件。
实际操作中,如果你只是在自己一台 VPS 上自用,创建管理员账号就够了,不用管这些。但如果你打算把它部署在公司的跳板机上供多人使用,我建议提前规划好用户权限矩阵,避免所有人都是管理员,谁都能动 Nginx 全局配置,那还不如不搞这套系统,直接给 root 权限拉倒。
另外要说明一点:Nginx UI 的用户体系和 Linux 系统用户是两套东西。Nginx UI 的登录账号只用来登录 Web 界面,最终执行 Nginx 命令的还是后端进程的系统身份。部署时建议让 Nginx UI 进程以 root 之外的专门用户运行,同时配置好 sudo 提权规则,这块内容我在第 4 部分详细演示。
2.6 在线终端与暗色主题等体验细节
除开上面这些"硬功能",Nginx UI 还有几个值得说的体验细节。
在线终端是一个 Web 版的终端模拟器,底层走 WebSocket 通道,打开之后就是服务器上的 shell。遇到临时要改个文件权限、查看一下进程状态这种小操作,就不用再另开一个 SSH 窗口了。它支持常见的终端操作,Vim 之类的全屏交互程序也能正常用,我实测过在在线终端里操作 fzf 也没问题。安全性上,它跟 Nginx UI 的登录会话绑定,你要是退出登录,终端连接也会断开。
UI 层面支持浅色/深色主题切换,深色模式对长期盯监控面板的人很友好。界面默认就是中文,对国内用户很友好,不用自己折腾汉化。
还有一个小细节:站点列表上可以直接看到每个站点的启用状态、SSL 状态、关联的 upstream 地址,整个仪表盘的信息密度比较高,扫一眼就知道整套服务器上有哪些站点、谁在跑、谁挂了。
3. 部署实操:从编译到跑起来
3.1 环境准备与前置条件
在开始部署之前,先确认服务器满足这几个条件:
- Linux 发行版不限,Debian/Ubuntu/CentOS/OpenEuler 都可以。macOS 也能编译运行,但生产环境建议还是 Linux。
- 目标机器上已经安装好了 Nginx 本体。Nginx UI 本身不携带 Nginx 程序,它只是管理 Nginx 的一个前端面板。没有 Nginx 的话,后面所有配置操作都是空中楼阁。
- 服务器能解析到你的管理域名,或者你打算直接用 IP+端口访问。建议用域名 + HTTPS 的方式访问 Nginx UI 管理后台,否则账号密码在网络上裸奔,风险太大。
- 如果要申请 Let's Encrypt 证书,需要保证 80 和 443 端口都能被外网正常访问。
我建议的服务器配置不低于 1 核 1G,部署完 Nginx 本体和 Nginx UI 之后内存占用大概在 200~300MB 左右,非常轻量。如果你还要在同一台机器上跑数据库和业务应用,那根据实际情况调整配置即可。
3.2 编译安装与前端构建
Nginx UI 提供了两种安装方式:直接下载 Release 二进制包,或者从源码编译。
对于大多数人来说,直接下载 Release 包是最省事的。它的 GitHub Release 页面会为不同架构提供预编译好的二进制包,比如 amd64、arm64 都有。下载下来的是一个压缩包,解压之后里面有 nginx-ui 可执行文件和 app.ini 配置文件模版,之后直接按第 3.3 节的方法初始化运行即可。
如果你对时效性有要求、想体验最新代码,或者需要改一些交互逻辑,再考虑源码编译。编译环境需要 Go 1.21 以上和 Node.js 16 以上的版本。以 Debian 系系统为例,先装基础工具链:
apt update && apt install -y git build-essential然后把项目克隆到本地并进入目录:
git clone https://github.com/xJacky/nginx-ui.git cd nginx-ui前端和后端是分开构建的。先处理前端资源,它默认基于 Vite 打包;我这里用 pnpm,你也可以用 npm,效果一样:
# 安装前端依赖 npm install -g pnpm pnpm install # 构建前端静态资源,默认输出到 dist 目录 pnpm build构建完之后,前端静态资源会生成在项目根目录下的dist文件夹里。接下来处理后端,后端是一个 Go 项目,构建的时候需要把前端产物嵌入到二进制包里,这样最后只需要分发一个文件就能跑整个服务。这个嵌入逻辑走的是 Go 的 embed 机制,构建脚本里已经处理好了。
# 生成嵌入前端的静态文件包 go generate ./... # 编译后端主程序 go build -o nginx-ui main.go编译完成后,项目目录下会多出一个 nginx-ui 二进制文件。把dist目录、app.ini、nginx-ui文件放到同一个目录下,这样一个"绿色版"部署包就做好了。传到服务器上任意目录,这台机器就算有了管理面板的"程序体"。
这里有一个容易踩的坑:如果你只执行go build而没有执行go generate,或者前端pnpm build之后直接编译,那打出来的二进制里可能没有前端页面。运行之后访问 Web 界面会白屏,只有接口数据没有页面元素。我的经验是严格按上面顺序操作,前三步缺一不可,构建完成后检查一下二进制包的大小——如果正常嵌入了前端资源,包体至少在 50MB 以上,如果只有十几 MB,那基本可以断定前端资源没打进去。
3.3 初始化配置与 systemd 托管
拿到二进制文件后,在放置 nginx-ui 文件的目录下执行:
./nginx-ui第一次启动时它会自动生成一个默认的app.ini配置文件,并且会提示你设置管理员账号。之后在浏览器里访问http://你的服务器IP:9000,用刚才设置的管理员账号登录。
配置文件app.ini里最核心的几个参数如下:
[Server] # 面板监听端口,默认 9000,可以改成内网专用端口 HttpPort = 9000 [Database] # 默认使用 SQLite 单文件数据库,路径相对于程序目录 Path = ./nginx-ui.db [Nginx] # 这里是指向系统 Nginx 可执行文件的绝对路径 NginxBinPath = /usr/sbin/nginx # Nginx 配置目录路径 NginxConfigDir = /etc/nginx建议把面板监听端口改成一个不太显眼的端口,比如 9118,然后通过 Nginx 反向代理到子路径,再用 you-get 之类的方式管理访问。我实际部署时的做法是:Nginx 80 端口做一个专门的反向代理到 127.0.0.1:9118,再配一层 HTTPS,这样管理入口变得比较干净,而且不会和其他站点抢端口。
把服务托管给 systemd 实现开机自启,这里给一份我常用的 unit 文件:
[Unit] Description=Nginx UI After=network.target nginx.service [Service] Type=simple WorkingDirectory=/opt/nginx-ui ExecStart=/opt/nginx-ui/nginx-ui Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target保存到/etc/systemd/system/nginx-ui.service,然后执行:
systemctl daemon-reload systemctl enable --now nginx-ui systemctl status nginx-ui看到active (running)就说明部署成功了。注意 WorkingDirectory 一定要指向你放置 nginx-ui 和 app.ini 的目录,否则程序可能找不到数据库文件,又会生成一个新的实例,两个实例同时跑就会出现端口冲突、数据文件错乱的问题。
4. 进阶玩法与实际站点配置
4.1 使用 Nginx UI 配置反向代理与静态站点
部署好 Nginx UI 之后,最常用的操作就是创建站点。我以反向代理为例,完整走一遍流程。
打开左侧菜单"站点管理",点击"新建站点",填写以下关键信息:
- 域名:填写你要对外提供服务的域名,例如
api.example.com - 监听端口:默认 80,同时勾选 443(前提是证书已配置好)
- 类型:选择"反向代理"
- 目标地址:填写后端服务的实际地址,例如
http://127.0.0.1:8080
保存之后,Nginx UI 会生成一段类似下面的配置:
server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 60s; } }默认配置下常用头部基本都会帮你带上。但如果你后端服务比较挑,例如拿到了真实客户端 IP 才能做限流,那记得在"高级配置"里再补一层 real IP 模块相关的配置,这里不展开。
静态站点的场景也类似。新建站点时类型选"静态站点",指定root目录和index文件,再勾选"启用 HTTPS"和"自动申请证书",基本就是两三分钟的事。对于用 Vue/React 打包出来的单页应用,记得在高级配置里手动补一段:
location / { try_files $uri $uri/ /index.html; }这种场景在 Nginx UI 的默认模板里不会自动生成,需要你在配置文件的编辑器模式下自行加上。第一次创建单页应用站点的时候,我因为没有加这段规则,刷新页面后全部 404,排查了半天才反应过来。
4.2 站点启停、日志查看与备份恢复
Nginx UI 的站点列表里,每个站点都有一个"启用/停用"开关。实际操作上,停用站点不是粗暴地删掉配置文件,而是在 conf.d 对应的文件名上做调整并 reload,例如把example.conf重命名成example.conf.bak。这个逻辑很安全,想恢复服务只需要再点一次启用作弊即可,不会再出现误删配置导致整站宕机的低级事故。
日志查看方面,Nginx UI 没有做复杂的日志检索,它把"错误日志"和"访问日志"文件路径展示在站点详情页里,点击就能跳到在线终端配合 tail 命令实时跟踪。如果你需要类似 GoAccess 那样可视化的日志分析报表,它不会帮你生成,需要自己另搭方案。
再说备份恢复。因为核心数据就两个:一个是nginx-ui.db(SQLite 数据库),负责保存站点配置元数据;另一个是/etc/nginx/下实际的 conf 文件。所以备份策略非常简单:
# 备份数据库 cp /opt/nginx-ui/nginx-ui.db /backup/nginx-ui-$(date +%F).db # 备份 nginx 配置目录 tar czvf /backup/nginx-conf-$(date +%F).tar.gz /etc/nginx/恢复时更简单:把 db 文件放回原目录、把 conf 文件解压回/etc/nginx/,启动 Nginx UI 服务即可。它不会像某些商业化面板那样悄悄改掉你的 conf 文件格式,所有配置都是标准的 Nginx 语法,这意味着即使某天你不再使用 Nginx UI,历史配置也完全可迁移、可维护,不存在被"绑定"在一套私有配置格式上的问题。
这一点我觉得是开源运维工具该有的操守——工具是帮你生成标准配置,而不是创造一套只有它能读懂的"黑话格式"。
5. 常见问题排查与避坑指南
5.1 部署与配置常见问题速查
| 问题现象 | 可能原因 | 处理办法 |
|---|---|---|
| 访问管理界面白屏 | 前端资源未嵌入二进制 | 按 3.2 节顺序重新构建,检查二进制体积是否大于 50MB |
| 新建站点后网站 404 | 缺少 try_files 规则 | 静态站点场景补 try_files 指令,单页应用补 index.html 回退 |
| 证书申请失败 | 域名解析到 CDN 或未开放 80/443 端口 | 临时关闭 CDN 回源,或检查安全组入站规则 |
| 保存配置后 Nginx 未生效 | PHP 文件权限问题、reload 权限不足 | 查看 /var/log/nginx/error.log,确认运行用户对 conf 目录有写权限 |
| 两个面板实例同时运行 | WorkingDirectory 配置错误 | systemd 里指定正确的目录,避免生成第二份 db 文件 |
| 在线终端连接断开 | 服务端 WebSocket 超时 | 检查代理层超时配置,设置 proxy_read_timeout 180s |
5.2 实操心得与避坑经验
第一个坑是安全问题。Nginx UI 默认没有任何访问 IP 限制,一旦开了公网端口,任何人都能打开你的登录页。虽然它有登录密码保护,但暴力破解的风险总归存在。我的处理方式是:把监听地址从 0.0.0.0 改成 127.0.0.1,然后借助 Nginx 本体的反向代理去暴露面板,再配合 basic auth 做一层额外校验。改监听地址只需要把app.ini里的HttpHost从默认值 0.0.0.0 改成 127.0.0.1 就行,实际这样配置之后面板只能从本机访问,从外网访问需要走 Nginx 代理。
第二个坑是权限问题。Nginx UI 进程默认用自己的运行用户去执行nginx -t和 reload。如果 Nginx 主进程的配置目录权限比较苛刻,比如目录属主是 root 而且没给其他用户写权限,那 Nginx UI 执行 reload 就会失败。解决方法是把 Nginx UI 的运行用户加入 Nginx 同组,或者给NginxConfigDir设置 755 权限,再不行就通过 sudoers 单独授权 nginx-ui 用户执行 reload 命令。这块不要图省事直接让 Nginx UI 跑在 root 下,面板这类带 Web 入口的程序一旦被攻破,root shell 落到别人手里就不是小事了。
第三个坑是配置文件的"路径锚定"。Nginx UI 在生成站点配置时会把include目录告诉 Nginx,默认是/etc/nginx/conf.d/。如果你系统和默认路径不一致(比如某些定制发行版把配置放在/usr/local/etc/nginx/),记得先在app.ini里把路径指对,否则你新建的站点会写到 Nginx 根本不读取的目录,站点建好了但就是不出效果。
第四个经验是关于流量报表的认知。Nginx UI 的状态监控更多是给"当下"看的,不是给"趋势分析"用的。真正需要月级、季度级流量报表的场景,我建议从/etc/nginx/conf.d/里把 access_log 单独指到独立文件,再用 Filebeat 或 Promtail 采集到日志搜索平台。这个思路能帮你把 Nginx UI 的轻量监控和重量级日志体系分开,各司其职。
5.3 与现有运维体系无缝共存
最后聊一下 Nginx UI 怎么跟现有运维体系共存的。很多人在引入可视化面板时最担心的就是:它会不会把原来的配置文件打乱、搞出外人看不懂的东西?
我实测下来,Nginx UI 的并发协议设计得比较克制。它生成的文件格式非常标准,而且你原有手写的 conf 文件它不会主动去动,面板只会管理它自己创建的站点。如果你在命令行里手动修改了一个站点的 conf 文件,回到面板刷新后它会把新内容读取回来同步显示,不会强制覆盖。但反过来,如果你在面板里编辑保存了同一个文件,那命令行里的旧改动自然就被覆盖掉了。这个"以最后一次保存为准"的逻辑,也提醒了团队协作时要注意:同一个时段不要同时用面板和命令行去改同一个配置文件,容易互相覆盖。
我现在的工作流是:常规操作走 Nginx UI,特殊需求走命令行,两边始终保持同步。既不用为了跑一个站点去背几十条 Nginx 指令,也没有被图形界面限制住手脚。对我自己来说,这个工具把日常运维里最琐碎的那部分工作稳稳地接住了。
最后再补充一个小技巧:Nginx UI 的管理界面支持直接绑定自己的域名并自动申请证书,这样你访问面板本身也是 HTTPS 的,登录凭证不会在网络上明文传输。我自己的管理域名是nginx.example.com,在面板设置里填好域名之后它就直接完成了证书签发,后续浏览器打开自动就是绿色小锁,省心不少。
在最后,我把这个项目值得一试的理由总结成一句大白话:如果你每天都在跟 Nginx 配置文件打交道,又希望少背点命令、多留点精力干正事,那开源的 Nginx UI 是现阶段很值得部署的一套方案。它可能不是银弹,但绝对能让你从"命令行炼丹"里解脱出来大半。搞一台测试服务器,按照上面的步骤部署一遍,相信你会很快感受到它的好处。