ccrun 用户多实例 systemd 服务完整部署文档
目录
ccrun用户多实例systemd服务完整部署文档
一、名词解释
- 模板文件名:
ccrun-lark-bridge@.service文件里的@代表这是实例化模板,支持多套脚本共用一份配置文件。 - 命令中
ccrun-lark-bridge@testccrun-lark-bridge:模板文件前缀名称@:固定分隔符test:实例标识,对应模板内变量%I
%I替换逻辑 命令里@test的test会填充到配置里%I位置ExecStart=/home/ccrun/%I.sh run→ 实际执行/home/ccrun/test.sh run
%I.sh 脚本示例
以上面的 test 实例为例,对应的业务脚本 /home/ccrun/test.sh 典型写法如下:
#!/bin/bash
export LARK_CHANNEL_HOME="$HOME/%I"
lark-channel-bridge "$@"执行流程:systemctl --user start ccrun-lark-bridge@test → systemd 将 %I 替换为 test → 执行 /home/ccrun/test.sh run → 脚本设置实例独立配置目录(LARK_CHANNEL_HOME),调用 lark-channel-bridge 并透传参数。
注意:脚本必须添加执行权限,否则启动报 203/EXEC:
chmod +x /home/ccrun/test.sh二、前置配置(仅首次部署执行)
2.1 创建统一环境变量文件 service_env
解决systemd后台服务PATH缺失问题,所有实例共用一套环境
cat > /home/ccrun/service_env <<EOF
# 同步SSH终端完整PATH,后台服务可识别所有自定义程序目录
# 注意:文件内不能写export,不支持$PATH/$HOME变量解析,路径必须硬编码
PATH=/home/ccrun/.local/bin:/opt/node22/lib/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# 可在此追加全局共用环境变量
EOF2.2 创建用户服务目录并生成模板
# 创建用户服务存放目录
mkdir -p /home/ccrun/.config/systemd/user
# 写入用户服务模板
cat > /home/ccrun/.config/systemd/user/ccrun-lark-bridge@.service <<EOF
[Unit]
Description=CCRun Bridge Instance %I
After=network.target
[Service]
Type=simple
# User=ccrun
# 注释说明:
# 1. --user 用户级服务不支持开启User参数,取消注释会直接报216/GROUP启动失败
# 2. 用户服务默认以当前登录ccrun账号运行,无需手动强制声明执行用户
# 统一加载全局PATH环境,补齐后台缺失的程序搜索目录
EnvironmentFile=/home/ccrun/service_env
ExecStart=/home/ccrun/%I.sh run
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF2.3 开启用户常驻+重载配置
# 开启linger,退出SSH登录服务不会被杀死
loginctl enable-linger ccrun
# 重载用户服务配置,加载新建模板
systemctl --user daemon-reload三、实例启停与自启操作(以实例test为例)
1. 立即启动 + 开机自动启动
systemctl --user enable --now ccrun-lark-bridge@test2. 仅临时启动,不加入开机自启
systemctl --user start ccrun-lark-bridge@test3. 仅停止服务,保留开机自启配置
systemctl --user stop ccrun-lark-bridge@test4. 停止服务 + 取消开机自启(彻底清理实例)
systemctl --user disable --now ccrun-lark-bridge@test5. 修改脚本/环境后重启实例
systemctl --user restart ccrun-lark-bridge@test四、状态查看命令
# 查看实例运行状态、进程、报错信息
systemctl --user status ccrun-lark-bridge@test五、日志查看命令
1. 实时滚动日志(调试实时输出)
journalctl --user -u ccrun-lark-bridge@test -f2. 查看今日全部日志
journalctl --user -u ccrun-lark-bridge@test --since today3. 只输出最近100行日志
journalctl --user -u ccrun-lark-bridge@test -n 1004. 查看全部历史日志
journalctl --user -u ccrun-lark-bridge@test六、批量管理示例(拓展)
批量注册开机自启并启动多个实例
for name in test test demo; do systemctl --user enable --now ccrun-lark-bridge@$name; done批量停止并取消全部实例自启
for name in test test demo; do systemctl --user disable --now ccrun-lark-bridge@$name; done七、重要补充说明
- 本方案为用户级服务,所有操作命令必须携带
--user;仅登录ccrun用户生效,无法在配置内启用User=ccrun,启用会报216错误。 - 全程仅一份service模板文件,新增/删除实例无需新建配置,只需要新增对应
xxx.sh脚本。 - systemd后台用户服务不会加载bash登录脚本,PATH环境极度精简;通过
service_env统一补齐完整PATH,脚本内简写命令可正常识别。 - service配置内
Environment="PATH=xxx"不支持$PATH变量拼接,只能硬编码路径;推荐使用EnvironmentFile统一管理环境变量。 - 业务主程序建议在脚本内使用绝对路径执行,不受PATH环境变动影响,兜底防止203启动失败。
八、常见故障排查
1. 报错 code=exited, status=216/GROUP
原因:模板中存在未注释的User=ccrun,用户服务禁止手动指定运行用户
修复:注释User=ccrun → systemctl --user daemon-reload → 重启实例
2. 报错 code=exited, status=203/EXEC
代表程序无法执行,三种常见诱因:
① 脚本无执行权限:chmod +x /home/ccrun/xxx.sh
② 程序依赖PATH缺失:核对service_env内PATH是否包含程序目录
③ 脚本内使用简写命令,未写绝对路径,建议主程序替换为完整路径
3. 登录退出后服务自动关闭
修复:执行loginctl enable-linger ccrun开启用户常驻