At Inbox we're using Phabricator to review all code going to production. It's a great tool that enables us to easily learn from each other and increase the quality of the code we're writing.

Phabricator is pretty easy to install, but it requires running a bunch of daemons that perform background tasks. It provides a wrapper script called phd which, when invoked, spins up the default set of daemons and backgrounds them. Unfortunately, since it backgrounds the processes, it doesn't play well with the excellent Supervisor, which allows one to automatically bring the daemons up after a reboot or if they crash, since supervisor requires managed processes to stay in the foreground.

If you try to use the obvious phd launch under supervisor... wat wat.

$ supervisorctl status
phd              FATAL      Exited too quickly (process log may have details)

The process error log ends up looking like:

phd start: Unable to start daemons because daemons are already running.
You can view running daemons with 'phd status'.
You can stop running daemons with 'phd stop'.
You can use 'phd restart' to stop all daemons before starting new daemons.

supervisor starts the daemons, but it can't tell that they're running because they automatically background themselves!

There's a debug mode to phd, but running in production we don't necessarily want /var/log to fill up with mountains of debug spew.

Instead, stick the following in your supervisor configuration (on Debian/Ubuntu, paste into the new file /etc/supervisor/conf.d/phd.conf):

[program:PhabricatorRepositoryPullLocalDaemon]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorRepositoryPullLocalDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon.log
stderr_logfile=/var/log/supervisor/PhabricatorRepositoryPullLocalDaemon_err.log

[program:PhabricatorGarbageCollectorDaemon]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorGarbageCollectorDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon.log
stderr_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon_err.log

[program:PhabricatorTaskmasterDaemon1]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorTaskmasterDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon1.log
stderr_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon1_err.log

[program:PhabricatorTaskmasterDaemon2]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorTaskmasterDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon2.log
stderr_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon2_err.log

[program:PhabricatorTaskmasterDaemon3]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorTaskmasterDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon3.log
stderr_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon3_err.log

[program:PhabricatorTaskmasterDaemon4]
command=/srv/phabricator/scripts/daemon/phd-daemon PhabricatorTaskmasterDaemon --phd=/var/tmp/phd/pid
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon4.log
stderr_logfile=/var/log/supervisor/PhabricatorGarbageCollectorDaemon4_err.log

Make sure you're not running phd manually, restart the supervisor service (sudo service supervisor restart on Debian/Ubuntu) and you should be good to go.

(Much thanks to Evan Priestley for the quick support and explanation on #phabricator.) Note that this solution is officially not supported and could break.