目录

ccrun 用户多实例 systemd 服务完整部署文档

ccrun用户多实例systemd服务完整部署文档

一、名词解释

  1. 模板文件名:ccrun-lark-bridge@.service 文件里的 @ 代表这是实例化模板,支持多套脚本共用一份配置文件。
  2. 命令中 ccrun-lark-bridge@test
    • ccrun-lark-bridge:模板文件前缀名称
    • @:固定分隔符
    • test:实例标识,对应模板内变量 %I
  3. %I 替换逻辑 命令里 @testtest 会填充到配置里 %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
# 可在此追加全局共用环境变量
EOF

2.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
EOF

2.3 开启用户常驻+重载配置

# 开启linger,退出SSH登录服务不会被杀死
loginctl enable-linger ccrun

# 重载用户服务配置,加载新建模板
systemctl --user daemon-reload

三、实例启停与自启操作(以实例test为例)

1. 立即启动 + 开机自动启动

systemctl --user enable --now ccrun-lark-bridge@test

2. 仅临时启动,不加入开机自启

systemctl --user start ccrun-lark-bridge@test

3. 仅停止服务,保留开机自启配置

systemctl --user stop ccrun-lark-bridge@test

4. 停止服务 + 取消开机自启(彻底清理实例)

systemctl --user disable --now ccrun-lark-bridge@test

5. 修改脚本/环境后重启实例

systemctl --user restart ccrun-lark-bridge@test

四、状态查看命令

# 查看实例运行状态、进程、报错信息
systemctl --user status ccrun-lark-bridge@test

五、日志查看命令

1. 实时滚动日志(调试实时输出)

journalctl --user -u ccrun-lark-bridge@test -f

2. 查看今日全部日志

journalctl --user -u ccrun-lark-bridge@test --since today

3. 只输出最近100行日志

journalctl --user -u ccrun-lark-bridge@test -n 100

4. 查看全部历史日志

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

七、重要补充说明

  1. 本方案为用户级服务,所有操作命令必须携带 --user;仅登录ccrun用户生效,无法在配置内启用User=ccrun,启用会报216错误。
  2. 全程仅一份service模板文件,新增/删除实例无需新建配置,只需要新增对应xxx.sh脚本。
  3. systemd后台用户服务不会加载bash登录脚本,PATH环境极度精简;通过service_env统一补齐完整PATH,脚本内简写命令可正常识别。
  4. service配置内Environment="PATH=xxx"不支持$PATH变量拼接,只能硬编码路径;推荐使用EnvironmentFile统一管理环境变量。
  5. 业务主程序建议在脚本内使用绝对路径执行,不受PATH环境变动影响,兜底防止203启动失败。

八、常见故障排查

1. 报错 code=exited, status=216/GROUP

原因:模板中存在未注释的User=ccrun,用户服务禁止手动指定运行用户 修复:注释User=ccrunsystemctl --user daemon-reload → 重启实例

2. 报错 code=exited, status=203/EXEC

代表程序无法执行,三种常见诱因: ① 脚本无执行权限:chmod +x /home/ccrun/xxx.sh ② 程序依赖PATH缺失:核对service_env内PATH是否包含程序目录 ③ 脚本内使用简写命令,未写绝对路径,建议主程序替换为完整路径

3. 登录退出后服务自动关闭

修复:执行loginctl enable-linger ccrun开启用户常驻