Files
ykxmz/_build/install_halo.py
xmz7891 2061f9525f 2.3.0:手表界面精简 + 播放器 + 鼠标重做
手表端
- 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源)
- 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、
  剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等
- 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘
- 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮
  滚轮点按=中键、上下滑=滚动
- 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、
  点画面播放暂停、上一/下一、播完自动下一首

电脑端
- 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身
- 新增 media_list / media_pull(播放器数据源)
  安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过

中转站
- known_devices 从 ID 集合改成「设备ID -> 配对码」映射
- 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉
- 老格式 state 文件平滑升级
2026-10-18 11:39:14 +08:00

132 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
r'''第二步:装 Halo 博客(Docker)。
== 配置决策(以及为什么)==
**用 Docker 而不是裸 JAR**
机器上已经有 Docker 29.8(1Panel 装的),直接用。好处:
不用在系统里装 Java、升级只要换镜像 tag、环境隔离。
**数据库用内置 H2(不接 MySQL)**
个人博客用 H2 完全够 —— 数据就是一个文件。
接 MySQL 要多挂一个容器,多占 400MB+ 内存,而机器只有 1.9G。
**少一个组件就少一处会坏的地方。**
**端口绑 0.0.0.0:3001**
用户要求 "端口的话就跑在 <服务器IP>:3001" ——
所以要能从外面直接访问 3001。
同时 nginx 也要能反代(走域名)。
如果只绑 127.0.0.1,`IP:3001` 就不通了。
**限制 JVM 堆**
`-Xmx400m`。机器 1.9G,JVM 默认会按 1/4 物理内存要堆(约 470M),
再加元空间/线程栈/直接内存容易冲到 700M+。
显式限到 400M 更可控 —— 博客流量小,400M 绰绰有余。
**外部地址设成 https://xxmxxs.top**
Halo 用它生成文章链接和站点地图。设成域名之后,
就算你从 `IP:3001` 进来,页面里的链接也是域名 —— 这样更一致。
**控制台路径 /houtai**
用户要求 "xxmxxs.top/houtai 是管理博客的后台"。
Halo 2.x 支持自定义控制台路径(社区 PR #2453)。
默认是 /console,这里改成 /houtai。
⚠ 如果这个版本的 env 变量名不对,容器会起不来 —— 脚本里会检查。
== 数据目录 ==
/opt/halo/data -> 容器内 /root/.halo2
里面有 H2 数据库、上传的附件、主题。
**这个目录要备份** —— 它是博客的全部内容。
'''
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "_build"))
from lssh import run # noqa: E402
REMOTE = r'''
echo "==== 1. 看看有哪些可用的 Halo 版本 ===="
sudo docker pull halohub/halo:2 >/dev/null 2>&1 && echo " ✓ halohub/halo:2 拉下来了" || echo " ✗ 拉取失败"
sudo docker images halohub/halo --format ' {{.Repository}}:{{.Tag}} {{.Size}} ({{.CreatedSince}})' 2>/dev/null
echo
echo "==== 2. 看看镜像里支持哪些配置项 ===="
# Halo 的配置项在 application.yaml 里,从镜像里抠出来看
sudo docker run --rm --entrypoint sh halohub/halo:2 -c \
"find / -name 'application*.yaml' 2>/dev/null | head -5" 2>/dev/null | sed 's/^/ /'
echo
echo "==== 3. 准备数据目录 ===="
sudo mkdir -p /opt/halo/data
sudo chown -R 1000:1000 /opt/halo 2>/dev/null || true
ls -la /opt/halo | sed 's/^/ /'
echo
echo "==== 4. 起容器 ===="
sudo docker rm -f halo 2>/dev/null >/dev/null || true
sudo docker run -d \
--name halo \
--restart always \
--log-opt max-size=10m --log-opt max-file=3 \
-p 0.0.0.0:3001:8090 \
-v /opt/halo/data:/root/.halo2 \
-e HALO_EXTERNAL_URL=https://xxmxxs.top \
-e HALO_CONSOLE_PATH=/houtai \
-e JAVA_OPTS="-Xms128m -Xmx400m -XX:+UseSerialGC" \
halohub/halo:2 2>&1 | sed 's/^/ /'
echo
echo "==== 5. 等它起来(最多 90 秒)===="
ok=0
for i in $(seq 1 45); do
sleep 2
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 http://127.0.0.1:3001/ 2>/dev/null)
st=$(sudo docker inspect -f '{{.State.Status}}' halo 2>/dev/null)
if [ "$code" = "200" ] || [ "$code" = "302" ] || [ "$code" = "301" ]; then
echo " 第 $((i*2)) 秒:HTTP $code ✓ 起来了"
ok=1
break
fi
if [ "$st" != "running" ]; then
echo " 第 $((i*2)) 秒:容器已经退出(状态 $st)"
break
fi
done
if [ "$ok" != "1" ]; then
echo " 容器状态: $(sudo docker inspect -f '{{.State.Status}}' halo 2>/dev/null)"
echo " --- 日志(最后 30 行)---"
sudo docker logs --tail 30 halo 2>&1 | sed 's/^/ /'
fi
echo
echo "==== 6. 复核 ===="
sudo docker ps --filter name=halo --format ' {{.Names}} {{.Status}} {{.Ports}}'
echo " 首页: HTTP $(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:3001/)"
echo " /houtai: HTTP $(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:3001/houtai)"
echo " /console: HTTP $(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:3001/console)"
echo " 从外面直连 3001(本机自测):HTTP $(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:3001/actuator/health 2>/dev/null)"
echo
echo " --- 内存占用 ---"
sudo docker stats --no-stream --format ' {{.Name}} 内存 {{.MemUsage}} CPU {{.CPUPerc}}' halo 2>/dev/null
free -m | sed 's/^/ /'
'''
def main() -> int:
print("=" * 62)
print(" 第二步:装 Halo(Docker)")
print("=" * 62)
print()
out = run(REMOTE, timeout=900, quiet=True)
print(out[1] if isinstance(out, tuple) else out)
return 0
if __name__ == "__main__":
sys.exit(main())