项目部署成功后,事情往往还没结束。今天能打开的页面,明天会不会因为进程退出而失联?人在外面时,又该怎样确认服务状态?这次我用星空组网连接 Ubuntu 和访问设备,再部署 Uptime Kuma,给一个 Python 演示接口做持续检查。最后主动停止、恢复接口,用实际状态变化验证监控是否工作。
这套流程适合刚开始接触服务器和 Docker 的读者。我们先把一个检查项跑通,再理解地址、检测周期和故障记录的含义。监控界面只通过服务器的组网地址访问,不需要为本文额外开通公网管理端口。
一、先分清:谁负责连接,谁负责检测
星空组网负责让设备互相访问,Uptime Kuma 负责周期性请求目标、记录响应和状态。手机打开面板时,请求经过星空网络;监控容器检查演示接口时,请求走同一个 Docker 项目的内部网络。这是两条不同的路径,后面的验证也分别进行。
本文使用已经上线的设备成员,保留原有名称 Ubuntu-Board。文中地址是本次环境的示例;照做时要替换为自己客户端显示的组网地址。不要把服务器公网 IP、星空虚拟 IP 和 Docker 容器地址混用。
二、从官网登录,准备独立设备成员
打开星空组网官网,进入后台管理;没有账号时先完成注册,已有账号则直接登录。密码由自己输入,不放进截图和正文。此次浏览器已有登录状态,下图单独展示空白登录入口,后续操作使用现有后台会话。
图1:官网登录入口,截图未填写账号或密码。
进入“设备管理 → 成员列表”,为需要长期在线的设备分别准备成员。创建时填写便于识别的名称,例如 Ubuntu-Monitor;成员账号后缀可以使用 ubuntu_monitor。虚拟 IP 按当前账号能力设置,也可以交给系统分配,随后记录实际地址。官方成员管理说明强调,不要让多台长期在线设备共用同一个成员账号。
图2:添加成员的填写示例。本次已有可用成员,因此没有提交创建,也没有改变现有设备账号。
Ubuntu、电脑和手机分别使用各自的成员登录。回到列表,检查设备名称、虚拟 IP 和最后活跃时间。账号存在只能说明已建档;是否能访问业务,还要继续检查客户端与实际服务。
图3:按组网地址范围筛选本次 Ubuntu 与手机成员,核对地址和活跃状态。
三、核验 Ubuntu,先把组网地址用对
新机器可按官方 Linux 说明安装客户端,打开安装完成后提示的控制台地址,登录设备成员并确认在线。本次已有 6.1.0 客户端,不重复安装。下面按官方安装方式给出命令,并为下载失败增加curl错误返回;先阅读对应说明,再在需要安装的机器上执行:
sudo STARVPN_VERSION=6.1.0 bash -c "$(curl -fsSL https://file.starvpn.cn/stars/shell/prod/linux/install.sh)"部署之前检查系统、Docker、Compose、组网网卡和内存:
lsb_release -ds docker --version docker compose version ip -brief -4 addr show StarVPN free -h ss -lnt '( sport = :3001 )'网卡名以自己的设备为准;TUN 网卡输出 UNKNOWN 并不能单独证明掉线,还需看分配的地址和实际访问结果。端口 3001 已被使用时,先识别原服务,再为本文选择其他宿主端口。
本次 Docker 为 29.1.3,最初没有 Compose 子命令。确认现有 Docker 来自 Ubuntu 软件源后,只补装匹配的插件,实际版本为 2.40.3,没有重装 Docker:
sudo apt-get install --no-install-recommends docker-compose-v2如果你的 Docker 来自 Docker 官方软件源,应按对应安装文档补插件,不能直接混用包名。本文服务器总内存约 1.9 GiB,还有其他服务运行,因此下方配置给新增容器设置了内存和日志上限。
图4:本次环境检查,显示系统、Docker、Compose、组网地址和当时的内存状态。
四、创建项目,部署监控与演示接口
下面命令在具备目标目录和 Docker 操作权限的终端执行;本文实机使用 root 会话。单独建一个目录,避免与已有项目混在一起:
mkdir -p /opt/starvpn-monitor-demo-20260914 cd /opt/starvpn-monitor-demo-20260914创建health.py,写入以下代码。它只在/health返回正常状态;其他路径返回 404,方便区分“服务正常”和“地址填错”。这段程序只用于演示,没有用户数据,也不会列出目录文件。
import json from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer class HealthHandler(BaseHTTPRequestHandler): def do_GET(self) -> None: healthy = self.path == "/health" payload = {"status": "ok", "service": "starvpn-demo"} if healthy else { "error": "not_found" } body = json.dumps(payload).encode("utf-8") self.send_response(200 if healthy else 404) self.send_header("Content-Type", "application/json; charset=utf-8") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) if **name** == "**main**": with ThreadingHTTPServer(("0.0.0.0", 8000), HealthHandler) as server: server.serve_forever()同一目录创建compose.yaml:
name: starvpn-monitor-demo services: uptime-kuma: image: louislam/uptime-kuma:2 restart: unless-stopped ports: - "192.168.188.5:3001:3001" volumes: - kuma-data:/app/data mem_limit: 384m memswap_limit: 512m environment: NODE_OPTIONS: --max-old-space-size=256 logging: driver: json-file options: max-size: "5m" max-file: "2" demo: image: python:3.12-slim command: ["python", "-u", "/app/health.py"] restart: unless-stopped user: "10001:10001" read_only: true cap_drop: [ALL] security_opt: ["no-new-privileges:true"] volumes: - ./health.py:/app/health.py:ro mem_limit: 64m memswap_limit: 64m logging: driver: json-file options: max-size: "1m" max-file: "2" volumes: kuma-data:这里有三个容易忽略的细节。第一,192.168.188.5:3001:3001的第一个地址必须替换成服务器实际组网 IP;它将面板端口绑定在指定地址。第二,demo 没有ports,它的 8000 端口只用于容器间访问。第三,kuma-data保存监控配置和历史,普通停止容器不会删除它。
镜像来自 Uptime Kuma 与 Python 的官方仓库。louislam/uptime-kuma:2是会随发布变化的标签,本次日志确认运行 2.5.4;它不保证未来拉取仍是同一补丁版本。需要严格复现时应记录并固定实测镜像摘要。Uptime Kuma 官方部署说明
验证配置,再启动:
docker compose config --quiet docker compose up -d docker compose ps docker compose logs --tail 30 uptime-kuma配置检查没有输出且正常退出,再继续启动。若镜像拉取失败,先看下载错误,不要把“命令已经敲完”当成部署成功。本文两个容器启动后,又从演示容器内部检查接口:
docker compose exec -T demo python -c 'import urllib.request; r=urllib.request.urlopen("http://127.0.0.1:8000/health"); print(r.status, r.read().decode())'图5:两个容器 running,面板绑定组网地址,演示接口返回 200 与 JSON;截图同时记录当时内存占用。
五、初始化面板,添加第一条监控
电脑先连接星空组网,再在浏览器打开http://192.168.188.5:3001/。首次进入要选择数据库,本次选择界面推荐用于小规模部署的 SQLite;等待初始化完成后,设置独立的管理员账号与密码。
图6:首次启动选择 SQLite,数据保存在本项目的数据卷。
图7:管理员创建页面。密码由操作者本人设置,截图保留未填写状态。
进入管理页面后添加 HTTP(s) 监控,名称使用“演示健康接口”,目标地址填http://demo:8000/health。这里的 demo 来自 Compose 服务名,Uptime Kuma 容器能解析它;手机浏览器不能把它当作服务器地址。手机访问的仍是组网 IP 加面板端口。
为了快速观察变化,本次心跳间隔设置为20秒、请求超时5秒、重试次数0,有效状态码保留200~299,使用GET请求。demo是容器服务名,不适用域名过期检查,因此取消该选项。生产服务应根据容忍的延迟调整周期与重试,避免把偶发抖动都当成故障。
图8:填写服务名、容器内部URL和20秒检测间隔;其余参数按正文设置。
滚动到表单底部,点击“保存”,然后确认列表出现该项。本文实际创建的监控编号为1,首次检查记录为200 - OK。单看容器running还不够:只有监控服务真正请求到了目标接口,才能说明这条检查路径已经跑通。
本次只验证面板状态和事件记录,没有配置微信或邮件等外部通知。页面出现故障提示,不代表手机已经收到推送。
六、主动停止一次,验证故障与恢复
保持监控容器运行,在同一个项目目录只停止demo:
cd /opt/starvpn-monitor-demo-20260914 date -Is docker compose stop demo回到页面等待下一轮检查,不要刚执行命令就立即判断监控失效。本次停止命令约用了10秒,随后面板记录了5秒请求超时,状态转为红色“故障”。这证明检查项能够识别演示接口失联;这次故障来自主动停容器,并不是星空网络断开。
图9:停止demo后,监控变为故障,并显示timeout of 5000ms exceeded。
然后恢复同一个演示服务:
date -Is docker compose start demo等待后续检测成功,面板重新显示绿色“正常”,事件中新增200 - OK。恢复时无需重建监控,也不要清除历史;保留故障区段,才能看清变化过程。
图10:重新启动demo后恢复正常,心跳历史保留了之前的红色故障记录。
本次事件历史依次为18:34:02正常、18:34:22故障、18:35:22恢复正常。这里引用的是界面中的检查时间;它与日志写出时间可能存在差异,不能把两者混在一起推算精确检测延迟。
图11:事件记录保留完整的正常、故障、恢复链路,故障前后均为200 - OK。
仪表盘虽然列出24小时、30天和1年等统计栏,本项目只运行了短时间。当前百分比基于已有样本,不能当作长期在线率;故障期间的N/A也不等于响应耗时为零。
七、手机切换移动网络,验收远程访问
手机关闭Wi-Fi,使用移动数据连接星空组网,再用浏览器打开下面的地址。这里登录的是刚刚创建的Uptime Kuma管理员账号:
http://192.168.188.5:3001/dashboard/1末尾的1是本次监控编号;自己的编号不同,可以先打开首页,再从列表进入目标。不要在手机地址栏输入页面中绿色的http://demo:8000/health,它是供监控容器访问的内部地址。
图12:手机原始截图顶部可见5G和VPN标志,页面显示“演示健康接口”、20秒检测频率和绿色“正常”。
继续向下滚动,可以看到响应统计与历史曲线。这次手机截图还保留了前面故障演示对应的红色区域;后续绿色曲线说明监控继续产生检查结果。
图13:手机查看响应和历史曲线。当前4ms属于监控容器请求演示接口的耗时,不能当作手机5G延迟或星空组网测速结果。
两张截图的浏览器地址区域显示的是Uptime Kuma页面标题,没有展开完整URL;正文中的访问地址来自本次实际操作步骤。浏览器绿色图标也不能用来证明已经配置HTTPS。到这里,服务检查与手机远程查看两个环节分别有了可核对的结果。
八、遇到问题,按请求路径检查
手机打不开面板时,先检查手机与Ubuntu是否都在线,再核对组网IP及3001端口。服务器上执行下面命令,可区分应用本身没有启动和远程访问路径不通:
cd /opt/starvpn-monitor-demo-20260914 docker compose ps curl --max-time 5 -I http://192.168.188.5:3001/ docker compose logs --tail 30 uptime-kuma首页可能跳转到登录页,不能只用“是否返回200”判断它是否运行。还要实际打开页面、完成登录、看到监控项。Docker发布端口有自己的转发规则,不能仅凭UFW已启用就断言端口受到了预期限制;本次配置限定绑定组网IP,没有新增公网端口映射,也没有修改UFW规则。
面板能打开、检查项却故障时,重点核对http://demo:8000/health、容器状态和日志。误填127.0.0.1:8000,访问的是监控容器自己;把路径写成其他内容,会得到我们代码明确返回的404。将来监控另一台设备时,改填那台设备可达的组网地址与服务端口,并从监控端验证网络连通。
资源检查可以使用docker stats --no-stream和free -h。内存上限只是限制新增容器占用,不代表整台服务器一定够用;监控项数量增加后仍应观察实际消耗。镜像更新前记录版本并备份数据,避免直接覆盖唯一的数据副本。
监控与演示服务同在一台Ubuntu上,整台主机宕机时,面板也会一起失联。如果需要发现这类故障,应把监控放到另一台独立设备,再经星空网络检查目标。
暂时不用时,在本项目目录执行:
docker compose stop这会停止本文两个容器,保留数据卷。以后用docker compose start恢复。管理密码与星空成员密码分别保管;本次面板使用HTTP并限定组网访问,不能把浏览器界面写成已部署HTTPS。