站点部署
后台「站点部署」用来维护本机 Nginx 站点:保存域名与反代路径,预览配置文本,并用 Let's Encrypt 申请证书。把 Elysia Admin 自身用 Docker 或 PM2 跑起来,见 部署。
代码在 server/src/modules/system-deploy/。站点表 system_deploy_site、证书记录表 system_deploy_cert,字段见 数据库设计。
前置条件
证书申请和 Nginx 重载都在运行后端的那台机器上执行。
- 本机可执行
openssl(生成账户密钥与证书请求)和nginx(仅在开启自动重载时调用nginx -s reload) - 域名的 80 端口能访问到该机,Let's Encrypt 用 HTTP-01 读取
/.well-known/acme-challenge/ - 进程对网站校验目录、证书目录可写
- 定时续签依赖 Worker。任务名必须是「站点证书续签」,种子数据中的 Cron 为
15 3 * * *(每天 03:15)。库里没有这条任务时,在「定时任务」里按该名称新增并启用。详见 定时任务
ACME 账户密钥写在进程工作目录的 storage/certs/account.pem,账户 URL 写在同目录的 account.url。
站点字段
未删除站点的域名唯一。站点名只允许字母、数字、下划线和连字符,且以字母或数字开头(宝塔路径会拼进文件名)。
| 字段 | 说明 |
|---|---|
站点名 name | 用于宝塔 include、日志文件名 |
域名 serverName | Nginx server_name |
网站根目录 wwwRoot | 静态站点(管理端等)默认 root |
校验目录 webRoot | HTTP-01 文件根目录,默认进程工作目录 |
证书目录 certDir | 默认 storage/certs/<域名>,其下为 fullchain.pem、privkey.pem |
| 邮箱 | 开启自动续签时必填,作为 ACME 账户联系邮箱 |
自动续签 sslAutoRenew | 交给定时任务扫描 |
自动重载 reloadNginx | 续签成功后执行 nginx -s reload;关闭时需要自己到面板重载 |
宝塔目录 useBaota | 默认开启。配置中带宝塔 vhost include 与 /www/wwwlogs/ 日志路径 |
HTTP 跳 HTTPS httpRedirect | 仅出现在含证书的那份配置里;/.well-known/ 不跳转 |
反代 locations | 路径列表,见下一节 |
校验文件的绝对路径是 <webRoot>/.well-known/acme-challenge。预览接口会把 challengeDir、certDir 一并返回,详情和列表卡片也会带上解析后的绝对路径。
反代路径
未传 locations 时使用四条预设;传了数组则按数组保存,可以是空数组。
| kind | 默认 | 行为 |
|---|---|---|
home | / → 127.0.0.1:4002 | 反代 |
admin | /admin,静态目录取 wwwRoot | try_files 回退到 index.html |
api | /api → 127.0.0.1:4003 | 反代 |
rustfs | /zqwz/ → 127.0.0.1:9000,上传限制 50m | 反代,Host 使用 $host |
custom | 自填路径 | proxy 反代到端口,或 static 指向目录 |
路径以 / 开头,不能含 .. 和换行等特殊字符,同一站点内不能重复。更长的路径写在更前面,避免被短前缀截走。RustFS 只反代到本机,不要把 9000 端口暴露到公网。
若当前启用的存储配置名称是 RustFS,站点表单通过 GET /api/system/storage/rustfs-bucket 读取桶名,用作默认反代路径。存储配置见 文件存储。
预览配置
POST /system/deploy/preview/:id 只返回文本,不写 Nginx 文件。一次给出两份:
httpOnly:只监听 80,申请证书前先让校验目录可访问ssl:额外监听443 ssl与443 quic,引用证书目录里的fullchain.pem、privkey.pem
把对应文本放到面板或 vhost 后,由你自己重载 Nginx。宝塔开关打开时,配置会 include:
/www/server/panel/vhost/nginx/extension/<站点名>/*.conf/www/server/panel/vhost/nginx/well-known/<站点名>.conf/www/server/panel/vhost/rewrite/node_<站点名>.conf
这些文件不存在时,Nginx 检测会失败,需要在面板里先有同名站点,或关掉「宝塔目录」再预览。
申请与续签
签发走 Let's Encrypt 生产目录 https://acme-v02.api.letsencrypt.org/directory。每次续签都新建订单,有效期以返回的证书为准。成功后原子替换 fullchain.pem 与 privkey.pem(失败会留住旧文件),并写入 system_deploy_cert。同一站点只有一条 isCurrent = true 的未删除记录。
立即续签是 POST /system/deploy/renew/:id。定时任务调用同一逻辑,但只处理同时满足这两点的站点:sslAutoRenew 为 true,且没有 certExpireAt 或距离到期不足 30 天。
手动续签与定时扫描共用 Redis 锁 deploy-cert-renew(约 10 分钟)。锁被占用时,手动接口返回「正在续签,请稍后再试」,定时任务直接跳过。续签失败会把原因写到站点的「最近续签结果」和证书记录,不中断其他站点。
开启了自动重载且续签成功时,才会执行 nginx -s reload。命令不存在或返回非 0 时,接口仍视为证书已更新,文案里会提示到面板手动重载。
权限
路由都要求登录,权限码如下。
| 权限 | 接口 |
|---|---|
system:deploy:query | 列表、全部、详情 |
system:deploy:create | 创建 |
system:deploy:update | 更新 |
system:deploy:delete | 软删除 |
system:deploy:preview | 生成配置 |
system:deploy:renew | 立即续签 |
system:deploy:cert | 证书记录 |
