Skip to content

一键初始化 nginx

主机加进来后是裸 Linux 系统(可能装了 nginx 也可能没装),需要先把 nginx 跑起来。平台提供「一键初始化」按钮,9 步流水线全自动搞定,前端的步骤条 + 实时日志面板能完整看到每一步的执行结果。


入口

「主机管理」列表里点 「初始化 nginx」 按钮(nginx 状态非 INSTALLED_ACTIVE 的主机才能点)→ 弹出 NginxInitProgressModal:

  • 左侧:竖向 9 步 Stepper,每个步骤的状态有 pending(灰)/in_progress(蓝,带 loading 图标)/done(绿勾)/failed(红叉)
  • 右侧:深色实时日志区(自动滚到底,含「📌 主机 IP / nginx 监听 / 防火墙端口」诊断信息)+ 终态 Alert(成功/部分完成/失败)
  • 顶栏:连接状态 Tag(已连接 / 连接中... / 连接断开)+ 终态 Tag(成功 / 部分完成 / 失败)

modal 打开立刻 EventSource/api/host/nginx-init-streaming/{hostUnCode},后端在同一个 SSE 连接里完成鉴权 + 注册 emitter + 提交 init 任务,事件不会丢


9 步流水线

[1] CONNECT  → [2] PROBE_OS  → [3] INSTALL_NGINX  → [4] ENABLE_NGINX  →
[5] VERIFY_NGINX  → [6] PROBE_HTTP  → [7] CHECK_FIREWALL  →
[8] OPEN_FIREWALL  → [9] REPROBE_HTTP  → [SUCCESS / PARTIAL / ERROR]

1. CONNECT —— SSH 连接

host 表拿密文 → AES-256-GCM 解密 → MINA SSHD 2.13 SshClient.connect() 走 22 端口。

平台用的 SSH 客户端是 Apache MINA SSHD(sshd-core 2.13),不是 JSch / sshj。MINA SSHD 是异步 NIO 实现,长连接复用,适合高频 SSH 操作。

ed25519 公钥 / 私钥在 JDK 17 上要靠 I2P eddsa 0.3.0 解析,JDK 17 自带的 EdDSA 还没实装;BouncyCastle (bcprov-jdk18on 1.78) 兜底通用 JCA。平台启动时 SecurityProviderInitializer 把 I2P EdDSA 注册为 position 1,BC 注册为 position 2。

2. PROBE_OS —— 自动识别发行版

/etc/os-release 解析(HostProbeService 之前已跑过,这里复用 host.os_type)。UNKNOWN 直接 abort,提示用户先在「探测」按钮里手动确认。

3. INSTALL_NGINX —— 包管理器安装

os_type 选命令:

  • UBUNTUapt-get install -y nginx
  • CENTOSyum install -y nginx
  • ROCKYdnf install -y nginx

5 分钟超时。SSH channel 复用: 因为 Linux server 默认 MaxSessions=10,整个 init 流程里所有命令合并为 1 条尽量少的 channel(prepareNginxDirs / openFirewallPorts(80, 443) / diagnostics()),避免触发 SshChannelOpenException: open failed

4. ENABLE_NGINX —— 启动服务

systemctl enable --now nginx(Ubuntu/Rocky) 或 chkconfig nginx on && service nginx start(CentOS 7)。

5. VERIFY_NGINX —— 校验

nginx -v 2>&1 && systemctl is-active nginx,期望输出 active。 失败:status 写 INSTALLED_INACTIVE,前端显示红叉 + 失败原因。

6. PROBE_HTTP —— 平台主动 HTTP 探测

关键设计: 不在主机内 curl 127.0.0.1:80,而是 后端用 java.net.http.HttpClient 主动发 GET 请求到 http://<host>:80/(模拟外部用户访问),5 秒 timeout。

返回含义
HTTP 2xx / 3xx端口对外通,服务可用
HTTP 4xx服务在跑但路径不对(防火墙放行了,nginx 也起得来)
HTTP 5xx服务在跑但应用层错误
ConnectException / ConnectTimeout端口不通(被防火墙 / 云安全组拦截)

这一步是「外部访问」的真实验证,不是「主机自己访问」。如果不通,继续走 step 7-9 修防火墙。

7. CHECK_FIREWALL —— 防火墙状态

按 OS 选命令,鲁棒三段判断(not-installed / active / inactive):

  • UBUNTUcommand -v ufw + ufw status | grep '^Status: active'
  • CENTOS / ROCKYcommand -v firewall-cmd + systemctl is-active firewalld | grep '^active'

鲁棒处理:

  • active → 走 step 8
  • inactive → 尝试启动(UFW: yes | ufw enable;Firewalld: systemctl start firewalld),再 checkFirewall 复查,active 才继续
  • not-installed / unknown → 跳过 step 8,直接进 step 9 平台探测(可能云安全组已经放行,也可能完全封住,step 9 给出结论)

8. OPEN_FIREWALL —— 放行 80/443

按 OS 选命令,一条命令同时放行 80 + 443 + reload:

  • UBUNTUufw allow 80/tcp; ufw allow 443/tcp
  • CENTOS / ROCKYfirewall-cmd --permanent --add-port=80/tcp; firewall-cmd --permanent --add-port=443/tcp; firewall-cmd --reload

注: 防火墙不可用(not-installed / unknown / 启动失败)时,这一步标 failed不中断流程——继续走 step 9 平台探测,看实际情况。

9. REPROBE_HTTP —— 重测,决定终态

再一次 java.net.http.HttpClient GET http://<host>:80/,终态判定:

终态触发条件显示
SUCCESSHTTP 2xx/3xx绿色 banner + 访问地址 http://<host>/
PARTIAL(成功)HTTP 4xx/5xx(服务在跑但配置错)黄色 banner,提示检查 nginx server_name / 站点目录
PARTIAL(失败)平台仍然连不上黄色 banner + 5 条排查方向(云安全组 / SELinux / 公网 IP / nginx 监听 0.0.0.0 / 防火墙规则被覆盖)+ 完整诊断日志
ERROR任何中间 step 异常(如 OS 不支持)红色 banner + 异常信息

终态诊断日志(📌 部分)

step 9 后,无论成功失败,都会输出一条 ─── 诊断信息 ─── 区段,含 4 行:

─── 诊断信息 ───
📌 SSH 连接的主机(面板配置): 192.168.1.208
📌 主机网卡 IP: 192.168.1.208 10.0.0.1
📌 nginx 监听 (ss/netstat): LISTEN 0 511 *:80 *:* users:(("nginx",pid=1234,fd=6))
📌 防火墙端口: 80/tcp 443/tcp
──────────────

单条命令合并,1 个 SSH channel 拿全 3 项(节省 MaxSessions=10 槽位)。失败时 fallback 提示"SSH server MaxSessions 限制,可在 /etc/ssh/sshd_config 调大 MaxSessions 重启 sshd"。


常见失败原因 & 排查

平台探测不到主机 80 端口

  • 云安全组没放行 —— 腾讯云 / 阿里云 / AWS 安全组需在控制台放行 80/443,后端 firewall-cmd 改的是主机内 iptables,管不到云侧
  • SELinux 拦截 —— Rocky / CentOS 默认开启 SELinux,执行:
    bash
    sudo setsebool -P httpd_can_network_connect 1
    sudo setsebool -P httpd_can_network_relay 1
  • 主机没公网 IP —— SSH 通的 IP 是内网,公网 80 进不来。检查 ip -4 addr show 是否有公网网卡
  • nginx 没监听 0.0.0.0:80 —— 检查 /etc/nginx/sites-enabled/defaultlisten 80 default_server 是否被改成 127.0.0.1
  • 防火墙规则被覆盖 —— firewalld 重新加载后规则可能被 reset,检查 firewall-cmd --list-ports

探测输出 HTTP 5xx

  • 服务在跑但 /var/www/html/index.html 不存在或无权限
  • nginx root 指令指向的目录不对
  • 默认站点配置缺 index 指令(找不到 index.html)

SSH channel open failed

主机上 cat /etc/ssh/sshd_config | grep -i MaxSessions,默认 10,调大到 50:

bash
sudo sed -i 's/^#MaxSessions 10/MaxSessions 50/' /etc/ssh/sshd_config
sudo systemctl restart sshd

下一步

nginx 起来后,到 站点发布到主机 把构建产物推上去。

基于 VitePress 构建