原文地址: https://a-wing.top/ruby/2018/09/10/systemd_rails.html
这篇文章属于没什么卵用系列
我并不喜欢 capistrano
众所周知 rails 的项目启动用 RAILS_ENV=production bundle exec rails server -p 3000 -d
如果服务器经常重启。。最简单的办法:那我们就要把这条命令放在 /etc/rc.local 里 (目前 deb 系的发行版是保留的。本质上是用 systemd 来执行这里的命令)。。。
不过目前。大部分 Linux Distribution 都是 systemd 来启动的(gentoo 除外。gentoo 默认是 openrc,可以换成 systemd)
在改之前。我们先把 rails 监听的端口换成 unix sock
sed -i 's#port ENV.fetch("PORT") { 3000 }#bind "unix://\#{Rails.root}/tmp/sockets/puma.sock"#g' config/puma.rb
例如我的项目叫 kiss2u 大概是这样:
$ cat ~/.config/systemd/user/kiss2u.service
[Unit]
Description=KISS2U Puma application server
After=network.target
[Service]
WorkingDirectory=/home/a-wing/.srv/KISS2U
PIDFile=/home/a-wing/.srv/KISS2U/tmp/pids/puma.pid
ExecStart=/usr/bin/sh /home/a-wing/.srv/KISS2U/run.sh
[Install]
WantedBy=default.target
没错。这个是用户级 systemd
但由于 systemd 要写绝对路径。。但我可不想手动改 QAQ
然后我们定义一个 template,就像这样。定义几个标签
$ cat config/kiss2u.service.template
[Unit]
Description=KISS2U Puma application server
After=network.target
[Service]
WorkingDirectory=<DIR>
Environment=RAILS_ENV=production
PIDFile=<DIR>/tmp/pids/puma.pid
ExecStart=<BUNDLE> exec rails server
[Install]
WantedBy=default.target
在 bin 目录下创建生成真正的 systemd 的配置文件 bin/generate_service.sh
当然我们是要新建一个用户来跑的。不然 generate_service.sh 就没意义了
#!/bin/bash
SYSTEMD=kiss2u.service
cp config/${SYSTEMD}.template ${SYSTEMD}
sed -i s#\<DIR\>#`pwd`#g ${SYSTEMD}
sed -i s#\<BUNDLE\>#`which bundle`#g ${SYSTEMD}
echo "Install ~/.config/systemd/user/${SYSTEMD}"
echo "Please Run: systemctl --user start ${SYSTEMD}"
install ${SYSTEMD} -D ~/.config/systemd/user/${SYSTEMD}
rm ${SYSTEMD}
然后来使用 systemctl --user start kiss2u
就可以启动了
要开机启动的话 systemctl --user enable kiss2u
就可以
我在 rbenv 下测试是好使的。。。在有些环境下就会出现启动不了的情况。我也不知道是为什么啊 QAQ
如果你启动出问题请更改 ExecStart=
解决办法:兼容性最好ExecStart=
来启动一段 shell 脚本。在 shell 脚本里加载必要的变量
source ./config.sh
echo RAILS_ENV=${RAILS_ENV}
ruby -v
if test -e tmp/pids/server.pid
then
echo 'Restarting'
kill `cat tmp/pids/server.pid`
else
echo 'Starting'
fi
bundle install --path vendor/bundle
bundle exec rake db:migrate
bundle exec rails server -p ${PORT} -d
类似这样。。。好吧。我承认这很不优雅。。。不过兼容性最好。。
https://github.com/a-wing/KISS2U
参考文章: