OneFeed的push notification实现借助了Sneakers。 在部署服务时,Ruby环境是通过rbenv管理的,环境变量(比如API Token等)则通过rbenv-vars管理。 为了不“污染”root用户以及系统的稳定,希望新建一个专门的用户来运行服务。

可以通过foreman把Sneakers项目导出成Upstart或者systemd service。 因为Ubuntu 16.04用systemd替换了Upstart,所以尝试用systemd来启动服务。

sudo foreman export systemd /etc/systemd/user -a notification-service -u hong

因为想以非root用户来启动服务,所以导出时加了-u选项指定用户,/etc/systemd/user是存放systemd user unit的目录。 导出的.service文件里会出现User=hong语句。

尝试启动服务,

su - hong
systemctl --user start notification-service.target

却始终报错,Failed to connect to bus: No such file or directory ubuntu。 Google后发现是su的问题。不用su,直接以用户hong登陆系统后再运行systemctl,上面的错误就消失了。 但是通过ps命令没有发现相关的ruby进程。再通过journalctl -r发现了如下错误信息,

Failed at step GROUP spawning /bin/bash: Operation not permitted

这可能是systemctl --user一个bug。 一个解决方案是删除User=hong语句。但是删除该语句后,systemctl会尝试用root用户的ruby来启动服务。 因为root用户的ruby没有安装服务所依赖的gem,所以会启动失败。 而且以root用户来启动服务也违背了初衷。

到此为止,这次对systemd的尝试以失败告终。而且前前后后花费了一两天的时间。 所以专门的DevOps还是必须的🤔。