在 VPS 上部署 Gatus:把网站健康检查写进配置,迁移时连规则一起带走

部署 Gatus,将健康检查写进 YAML,保存状态历史,核对告警条件、配置变更与恢复流程。

·8 min运维工具

网站增加一个入口,就在监控界面里点几次;迁移机器以后,又得照着截图重新建项目。检查项多起来,谁改过超时、哪个地址已经废弃,很难说清楚。Gatus 把检查地址、间隔和成功条件放进 YAML,适合希望把监控规则作为配置维护的人。

这篇先建立一个小型健康状态页,保存历史,再安排告警验证。监控节点尽量放在与业务不同的 VPS 上,避免宿主机故障时一起停掉。配置文件方便审查,但地址写错、条件太宽或通知没有绑定,仍然会让页面显示与实际情况不符。

规则要表达你关心的结果

“返回 200”只能说明 HTTP 请求得到了相应状态码。错误页也可能返回 200,需要时再检查正文或 JSON 字段。业务提供专门健康接口时,明确这个接口检查到哪一层:只说明进程存活,还是也验证了数据库与关键依赖。

响应时间阈值不要从别人的配置照抄。不同地区与网络路径的基线不同,先观察正常请求,再决定怎样识别明显异常。监控节点测到的是它到目标的路径,不能把这一个结果写成所有用户的访问速度。

首次只加两三个确实需要看的入口,名称区分公开域名与内部接口。内部地址不要直接展示在公共状态页上;私人规则可以通过 SSH 或 VPN 查看。重要接口需要认证时用专门凭据,不把长期管理员 Cookie 塞进可公开的配置仓库。

把配置和历史放在两个目录

准备 Docker Engine、Compose 插件和可运行 Docker 的账号。这里先通过 SSH 转发看私人状态页,之后按需要接宿主机 Caddy。status.example.com 是自己的域名示例,不是现成可用的地址。

mkdir -p /opt/gatus/config /opt/gatus/data
cd /opt/gatus

保存为 compose.yaml。采用官方稳定镜像入口,通过 GATUS_CONFIG_PATH 指定文件,减少工作目录差异带来的困惑。应用端口只绑定宿主机回环地址。

services:
  gatus:
    image: ghcr.io/twin/gatus:stable
    restart: unless-stopped
    ports:
      - "127.0.0.1:8089:8080"
    environment:
      GATUS_CONFIG_PATH: /config/config.yaml
    volumes:
      - ./config:/config:ro
      - ./data:/data

stable 会跟随正式发布变化。第一次检查通过后,记录镜像摘要并固定,升级时读取发布说明。配置目录只读挂载,历史目录需要可写;不要把数据库文件意外放进只读的 config 目录。

两项检查先写完整

创建 config/config.yaml。将示例 URL 改为自己管理的真实入口,其中健康接口需要实际返回 {"status":"UP"} 这类符合条件的 JSON。如果应用没有这种接口,就删掉该项或改成现有响应,不能只把地址写上去。

storage:
  type: sqlite
  path: /data/gatus.db
endpoints:
  - name: public-homepage
    group: website
    url: https://www.example.com/
    interval: 60s
    conditions:
      - "[STATUS] == 200"
  - name: application-health
    group: website
    url: https://www.example.com/health
    interval: 60s
    conditions:
      - "[STATUS] == 200"
      - "[BODY].status == UP"

Gatus 默认内存存储的历史不会跨重启保存,这里明确使用 SQLite 并挂载目录。配置中的字符串条件有自己的语法,YAML 能解析不代表条件就一定合理。[BODY].status 指向 JSON 字段,不能拿它去检查普通 HTML 页面的某个段落。

docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 gatus
curl -I http://127.0.0.1:8089/

检查日志是否成功读取配置,页面里是否出现你写的项目。某项立即失败时,先核对实际返回内容。对自己的健康接口执行一次请求,查看状态码和响应体,能比盲目把所有条件放宽更快找到错误。

私人查看与公开状态页分开决定

在自己的电脑使用 SSH 转发,打开本机 18089 端口查看状态页,替换用户与服务器地址。

ssh -N -L 18089:127.0.0.1:8089 [email protected]

需要公开状态页时,先确认项目名称和详情不会泄露内部地址,再配置域名。宿主机 Caddy 添加如下站点段,验证后重载;代理在容器里时改用共享网络中的应用服务地址。

status.example.com {
    reverse_proxy 127.0.0.1:8089
}

这份站点段不提供额外登录保护。包含私人系统的状态页保留在 VPN 或经过认证的入口里,不直接照这个例子公开。需要应用自己的认证方式时,按当前 Gatus 文档配置,再用未登录窗口检查实际范围。

公开页面显示正常以后,仍要确认监控请求来自 Gatus 容器。容器内 DNS、网络与证书信任可能和宿主机不同,宿主机 curl 成功只是一条线索。日志持续显示网络或证书错误时,按容器实际请求路径排查,不关闭证书验证来掩盖问题。

配置变更要能看清差异

把不含秘密的检查规则放进私人 Git 仓库,修改名称、地址和间隔时提交一次说明。Webhook、账号密码和内部系统凭据单独管理,不能因为仓库“暂时私人”就把所有密钥混在规则文件里。

增加一个检查项后观察至少几轮结果,确认请求地址、状态条件和历史都符合预期。改间隔可能影响告警速度和目标负载,批量调整前先看请求总量。几十个项目都用很短间隔,会让监控本身成为额外压力。

配置多起来时可以按项目拆文件,但要遵循 Gatus 的合并规则:数组会追加,重复的简单字段可能造成歧义。不要在多个文件里重复定义相同名字却期望后一个自动覆盖前一个,具体行为要用当前版本验证。

告警需要两层设置

通知渠道配置负责“发到哪里”,检查项上的 alert 配置负责“什么时候发”。只写了渠道,项目没有绑定对应类型,并不会自动按预期提醒。选择现有可用渠道,按官方说明填写凭据,再设置失败次数、恢复次数与恢复通知。

先为自己控制的测试服务建立一个检查项,正常响应时观察为成功,随后让它返回不符合条件的结果,确认状态与通知实际变化。不要为了验证监控去停止正式网站。测试以后恢复响应,核对恢复消息也能收到,再把测试项移出正式列表。

失败阈值用来过滤短暂抖动,数值越大也会越晚提醒。结合检查间隔算清楚持续异常多久才触发,别把几次重试理解成只延迟几秒。需要夜间通知的项目还要确认接收设备不会静音或屏蔽渠道。

通知目标、业务站点和监控最好不要全部依赖同一台机器。那台 VPS 失去网络后,即便监控进程还在运行,也可能无法发送消息。至少保留一个独立渠道,并定期发送一次测试,不只在最初安装时验证。

状态红了以后看是哪条条件失败

状态码失败,先判断是 DNS、连接、HTTPS 还是应用响应。JSON 条件失败,保存实际响应,对照字段路径和预期值。响应时间条件失败,则核对网络、目标负载与平时基线,不能直接认定服务宕机。

同一时刻多个毫不相关的站点一起失败,检查监控节点的网络和 DNS;某一个网站失败,再结合其他访问路径判断目标问题。保留发生时间与请求结果,便于对应代理和应用日志。

历史记录只在持久目录确实可写时有意义。重建容器后过去的事件还应存在;如果消失,先查 storage 与挂载路径。不要只看容器自动重启就认为监控已经恢复原来的历史。

恢复规则和历史以后,再接通知

小型 SQLite 实例可以停止应用后打包 config、data 和 Compose,取得一致副本。打包前检查空间,失败以后恢复服务并处理错误。

cd /opt/gatus
mkdir -p /opt/backups
docker compose stop gatus
tar -czf "/opt/backups/gatus-$(date +%F-%H%M).tgz" compose.yaml config data
docker compose start gatus

备份复制到独立存储,并保存镜像版本。如果配置里含通知凭据,副本也要保护。恢复演练用不同的回环端口,先不启用正式通知,避免测试实例与原实例重复告警。

检查项目、条件、较早的历史和新产生的结果,确认完整以后再切域名与通知。迁移完成时记录交接时间,停用旧节点的检查,保留回退材料。下一次调整入口,就可以从配置差异里知道改了什么,不用再靠截图还原监控规则。