如何通过Systemd服务在RVM环境下启动Sidekiq/Bundler
问题描述
我已有一个运行Rails应用的Systemd服务,运行正常,配置如下:
[Service] Type=exec User=my-user Group=my-user WorkingDirectory=/home/my-user/my-app ExecStart=/bin/bash -lc "bin/rails server"
但引入Sidekiq后无法正常启动。正常登录时我可以通过bundle exec sidekiq -C config/sidekiq.yml运行Sidekiq,但Ruby版本及相关二进制文件仅在正常登录会话中才会加载。我尝试将两个进程放在同一个服务里启动,配置如下:
ExecStart=/bin/bash -lc "bin/rails server & /home/my-user/.rvm/bin/rvm in /home/my-user/my-app do bundle exec sidekiq -C config/sidekiq.yml"
解决方案
1. 拆分两个独立的Systemd服务
Systemd的设计逻辑是一个服务管理一个进程,把Rails和Sidekiq塞同一个服务里会导致进程管理混乱——比如其中一个崩溃后systemd没法正确重启、日志混在一起难排查,建议拆分:
Rails应用服务(保留原有配置即可)
原配置不用大改,/bin/bash -lc会自动加载用户的登录环境(包括RVM的Ruby配置),所以Rails服务能正常运行:
[Unit] Description=My Rails Application After=network.target [Service] Type=exec User=my-user Group=my-user WorkingDirectory=/home/my-user/my-app ExecStart=/bin/bash -lc "bin/rails server" Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Sidekiq独立服务
新建一个systemd服务文件(比如/etc/systemd/system/sidekiq.service),同样用/bin/bash -lc加载登录环境,确保Ruby和bundle路径正确:
[Unit] Description=Sidekiq Worker for My Rails App After=network.target my-rails-app.service Requires=my-rails-app.service [Service] Type=exec User=my-user Group=my-user WorkingDirectory=/home/my-user/my-app # 用bash -lc加载用户登录环境,自动引入RVM的Ruby配置 ExecStart=/bin/bash -lc "bundle exec sidekiq -C config/sidekiq.yml" Restart=always RestartSec=5 # 可选:指定日志输出路径,方便排查 StandardOutput=append:/var/log/sidekiq.log StandardError=append:/var/log/sidekiq.log [Install] WantedBy=multi-user.target
2. 直接指定RVM环境路径(可选)
如果不想用bash -lc,也可以直接在服务里写死RVM的Ruby环境路径,比如:
ExecStart=/home/my-user/.rvm/wrappers/ruby-X.X.X@my-gemset/bundle exec sidekiq -C config/sidekiq.yml
把ruby-X.X.X@my-gemset换成你实际使用的Ruby版本和gemset名称,这个路径可以登录后运行which bundle获取。
3. 启动并启用服务
配置完成后执行以下命令:
# 重新加载systemd配置 sudo systemctl daemon-reload # 启动并启用Rails服务(如果之前没启用) sudo systemctl enable --now my-rails-app.service # 启动并启用Sidekiq服务 sudo systemctl enable --now sidekiq.service
4. 排查问题的方法
如果还是启动失败,查看日志定位原因:
# 实时查看Sidekiq服务日志 sudo journalctl -u sidekiq.service -f # 实时查看Rails服务日志 sudo journalctl -u my-rails-app.service -f
日志里通常会明确提示找不到Ruby、bundle或者依赖缺失的具体信息。
内容的提问来源于stack exchange,提问作者faervan
相关产品推荐
相关产品推荐

