Files
ClassHelper/deploy/classhelper.service
T

81 lines
3.6 KiB
Desktop File
Raw Normal View History

# ---------------------------------------------------------------------------
# 班级小助手 · 服务端 systemd 单元(Linux)
#
# 这是**模板**:`deploy/install.sh` 会把占位符替换成真实值后安装到
# /etc/systemd/system/classhelper.service。手动部署时照着替换这四处即可:
#
# __NODE__ Node 可执行文件的绝对路径(内置运行时:<安装目录>/runtime/node/bin/node)
# __DIR__ 安装目录(默认 /opt/classhelper)
# __USER__ 运行服务的系统用户(默认 classhelper)
# __CONFIG__ 环境变量文件(默认 /etc/classhelper/config.env)
# __CONFIGDIR__ __CONFIG__ 所在目录(需要写权限,见下面的 ReadWritePaths)
#
# sudo sed -e 's#__NODE__#/opt/classhelper/runtime/node/bin/node#' \
# -e 's#__DIR__#/opt/classhelper#' \
# -e 's#__USER__#classhelper#' \
# -e 's#__CONFIGDIR__#/etc/classhelper#' \
# -e 's#__CONFIG__#/etc/classhelper/config.env#' \
# deploy/classhelper.service > /tmp/classhelper.service
# sudo install -m 644 /tmp/classhelper.service /etc/systemd/system/classhelper.service
# sudo systemctl daemon-reload && sudo systemctl enable --now classhelper
#
# 常用命令(也有对应的 classhelper 封装):
# classhelper status / start / stop / restart / logs -f
# systemctl status classhelper
# journalctl -u classhelper -f
# ---------------------------------------------------------------------------
[Unit]
Description=ClassHelper Server (班级小助手服务端)
Documentation=https://github.com/LoveChengke/ClassHelper
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=__USER__
Group=__USER__
WorkingDirectory=__DIR__
# 配置从这里注入(唯一的配置真身;安装目录里的 .env 是指向它的软链,见 docs/linux-deploy.md)。
# systemd 会剥掉值两侧的引号,所以同一份文件给 dotenv / shell source / systemd 三种读法都能用。
# 前面不加 "-":文件被删掉时直接启动失败,比拿着一份假配置跑起来更容易发现。
EnvironmentFile=__CONFIG__
ExecStart=__NODE__ server/dist/index.js
Restart=always
RestartSec=3
# Socket.IO 长连接较多:提高文件描述符上限
LimitNOFILE=65535
# 优雅退出:给在途请求与 websocket 收尾时间(index.ts 处理 SIGTERM/SIGINT)
KillSignal=SIGTERM
TimeoutStopSec=20
# 日志进 journald:journalctl -u classhelper
StandardOutput=journal
StandardError=journal
SyslogIdentifier=classhelper
# ---------------------------------------------------------------- 加固
# 为什么 ReadWritePaths 要给整个 __DIR__ 与配置目录,而不是只给 data/logs:
# 1) Web 端「数据库管理 → 一键切换」会在运行中改写 server/prisma/schema.prisma,
# 并把重新生成的 Prisma Client 编译进 server/dist/generated —— 那两处都在 __DIR__ 里;
# 2) 同一功能切换成功后要改写 __CONFIG__(DATABASE_PROVIDER / DATABASE_URL 两行)。
# ProtectSystem=full 默认把 /etc 与 /usr 设成只读,ReadWritePaths 是官方的"打洞"方式。
# 服务本来就以 __USER__ 身份运行,这里给的写权限没有超出它的既有边界。
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true
ReadWritePaths=__DIR__ __CONFIGDIR__
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
# 需要 AF_NETLINK:glibc 解析主机名(MySQL 主机 / GitHub API)时会用到
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
[Install]
WantedBy=multi-user.target