メインマシンとして使っているMac miniを自作サービスのサーバーとしても使っていて、 毎回立ち上げるのが面倒だったので自動で起動するようにした。

PATH周りでトラブったので備忘録を残しておく。

launchd

通常のアプリの起動ならGUIで設定することができるっぽいが、自作のRailsアプリなので launchdを使うことにした。

init.dsystemctlのmacOS版らしい。

plistファイル

plistファイルというのに実行するコマンドや条件を書いておいて、loadすると起動時に自動で実行されるようになる。

plistファイルは~/Library/LaunchAgents/に置いた。サーバーアプリケーションだから/Library/LaunchDaemons/に置くのが正解な気はするけど、 rootが実行するとなるとrbenvbundlerあたりがややこしくなりそうだったので避けた。試してないので案外すんなり通るかもしれないが。

以下がサンプル。ファイル名は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で実行する場所を選べる。 あと大事なのがStandardOutPathStandardErrorPath。これをちゃんと設定しておくとデバッグしやすい。

echo hogeの部分をrails sにしてやるだけで動くように見えるが実は動かない。ここの対処がキモだが、一旦後回しにしてplistをloadする方法を先に説明する。

plistのload

$ launchctl load local.mac.sample.plist

こんな感じ。 unloadする場合はunloadに変えればOK。

railsを実行する際の注意

ここがこの記事のメイントピック。 上述したように、単純にrails slaunchdから実行しようとしてもうまくいかない。

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>

参考