先看现象。Debian 12 上写了个 systemd 服务,unit 里写了 RuntimeDirectory=app 和 RuntimeDirectoryMode=0750,服务启动就报 cannot bind unix socket /run/app/app.sock: Permission denied,目录确实建出来了。

这类报错背后常见的原因有几处,逐个排除就行。RuntimeDirectoryMode 是 0750,运行用户不在属组里写不进去。另一种情况是User 配的是 app,但 RuntimeDirectory 建出来的属主是 root。

还有一种情况,ProtectSystem=strict 打开后 /run 下需要额外放行。

另外,tmpfiles.d 里有同名规则,服务重启时把权限又改了回去。

上来先看目录的属主和权限

ls -ld /run/app && systemctl show app -p User -p RuntimeDirectory -p RuntimeDirectoryMode

接着确认 unit 里的用户和组

systemctl cat app | grep -E 'User|Group|RuntimeDirectory'

再往下把属组和权限一起补齐

printf '%s
' '[Service]' 'RuntimeDirectory=app' 'RuntimeDirectoryMode=0770' 'User=app' 'Group=app' > /etc/systemd/system/app.service.d/runtime.conf

等前面都确认过,再重载后重启并验证 socket

systemctl daemon-reload && systemctl restart app && ls -l /run/app/

这类改动我都写进变更记录,过两周再出问题时能对上号。

我习惯把每一步的执行时间和结果记在一边,后面复盘省事。

怎么算真的好了,看的是同一批现象。/run/app 属主是 app:app、权限 770,app.sock 正常创建,服务状态是 active (running)。

提醒一点。RuntimeDirectory 在服务停止时会被删掉,别往里放要保留的数据;目录给 0770 比 0750 稳,组内进程都能写。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189