macOS起動時にrailsを走らせる
メインマシンとして使っているMac miniを自作サービスのサーバーとしても使っていて、 毎回立ち上げるのが面倒だったので自動で起動するようにした。
PATH周りでトラブったので備忘録を残しておく。
launchd
通常のアプリの起動ならGUIで設定することができるっぽいが、自作のRailsアプリなので
launchdを使うことにした。
init.dやsystemctlのmacOS版らしい。
plistファイル
plistファイルというのに実行するコマンドや条件を書いておいて、loadすると起動時に自動で実行されるようになる。
plistファイルは~/Library/LaunchAgents/に置いた。サーバーアプリケーションだから/Library/LaunchDaemons/に置くのが正解な気はするけど、
rootが実行するとなるとrbenvやbundlerあたりがややこしくなりそうだったので避けた。試してないので案外すんなり通るかもしれないが。
以下がサンプル。ファイル名はlocal.mac.sample.plistとでもしておく。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>local.mac.sample</string>
<key>ProgramArguments</key>
<array>
<string>echo</string>
<string>hoge</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/shidetake</string>
<key>StandardOutPath</key>
<string>/Users/shidetake/sample.plist.log</string>
<key>StandardErrorPath</key>
<string>/Users/shidetake/sample.plist.log</string>
</dict>
</plist>
WorkingDirectoryで実行する場所を選べる。
あと大事なのがStandardOutPathとStandardErrorPath。これをちゃんと設定しておくとデバッグしやすい。
echo hogeの部分をrails sにしてやるだけで動くように見えるが実は動かない。ここの対処がキモだが、一旦後回しにしてplistをloadする方法を先に説明する。
plistのload
$ launchctl load local.mac.sample.plist
こんな感じ。 unloadする場合はunloadに変えればOK。
railsを実行する際の注意
ここがこの記事のメイントピック。
上述したように、単純にrails sをlaunchdから実行しようとしてもうまくいかない。
PATHの問題
どうやらlaunchdで実行する際には通常のPATHが通ってないらしい。
なので、単にrailsと入力しても、そんなコマンドはないと怒られてしまう。
ならばフルパスにしたら終わりかと思ったらそうでもない。
なぜか発生するJavascriptのランタイムエラー
エラー名でググっても、nodejsを入れたらいいとか、そんなのしか出てこない。 普通に実行するときはできているので、そういう問題ではない。
おそらくこれもPATHの問題と思われる。結局railsだけでなく、依存関係のあるプログラムもPATHが通ってないと動かない。まぁ当然だ。
launchdに環境変数を設定する方法
plistにEnvironmentVariablesというパラメータを設定してやると、環境変数を設定できる。
ただしこれを使うには/bin/zsh -c rails sというように一度zshを起動してやる必要がある。理由は不明。
完成形のplist
ということで、PATHを正しく設定して、zshを起動してその中で実行する形にしたのがこれ。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>local.mac.rails</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/Users/shidetake/.rbenv/shims:/Users/shidetake/.rbenv/bin:/usr/local/bin:/usr/bin:/bin</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>rails s</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/shidetake/git/rails</string>
<key>StandardOutPath</key>
<string>/Users/shidetake/git/rails/rails.plist.log</string>
<key>StandardErrorPath</key>
<string>/Users/shidetake/git/rails/rails.plist.log</string>
</dict>
</plist>