Page MenuHomePhabricator

Document (the lack of) init scripts for phd, and be more explicit about `phd launch`
Closed, DuplicatePublic

Description

The phd doc is nice but leaves for me the following topics open:

  • how to start phd at boot, is there a init script?
  • how can i define which daemons are started by "phd start" i.e. we want to start the IRC (chat) bot

Event Timeline

hwinkel raised the priority of this task from to Needs Triage.
hwinkel updated the task description. (Show Details)
hwinkel added a project: Phabricator.
hwinkel added a subscriber: hwinkel.
  • We don't ship with an init script because init scripts vary widely across operations systems and we don't have the time or experience to maintain one for each OS. You should be able to figure out how to write a script using your OS documentation.
  • In general, you can not control what phd start launches. If you want to launch additional daemons, use phd launch to bring them up explicitly, after running phd start.
epriestley renamed this task from please extend phd daemon documentation to Document (the lack of) init scripts for phd, and be more explicit about `phd launch`.Dec 1 2013, 2:51 AM
epriestley triaged this task as Low priority.

or use systemd service:

  1. create file

/lib/systemd/system/phabricator-phd.service

[Unit]
Description=phabricator-phd
After=syslog.target network.target
Before=apache2.service
User=wwwrun
Group=www

[Service]
Type=oneshot
Enviroment="PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/srv/www/htdocs/phabricator/bin/phd start
ExecStop=/srv/www/htdocs/phabricator/bin/phd stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
  1. register service in systemd
systemctl enable phabricator-phd.service
  1. start and check status
service phabricator-phd start
service phabricator-phd status
  1. profit
phabricator-phd.service - phabricator-phd
          Loaded: loaded (/lib/systemd/system/phabricator-phd.service; enabled)
          Active: active (exited) since Thu, 2014-08-21 12:37:41 YEKT; 9s ago
          Process: 518 ExecStart=/srv/www/htdocs/phabricator/bin/phd start (code=exited, status=0/SUCCESS)
          CGroup: name=systemd:/system/phabricator-phd.service
                  ├ 523 php /srv/www/htdocs/phabricator/scripts/daemon/phd-daemon PhabricatorRepositoryPullLocalDaemon --verbose --daemonize --log=/var/tmp/phd/log/daemons.log --phd=/var/tmp/phd/...
                  ....

Aug 21 12:37:39 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorGarbageCollectorDaemon".
Aug 21 12:37:39 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:39 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:40 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:40 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:40 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:41 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:41 phabricator.dtperm.ru phd[518]: Launching daemon "PhabricatorTaskmasterDaemon".
Aug 21 12:37:41 phabricator.dtperm.ru phd[518]: Done.

Thanks, mr.jsdive, that systemd service was very helpful.

  • systemd service for Centos7
/lib/systemd/system/phabricator-phd.service
[Unit]
Description=phabricator-phd
After=network.target
Before=httpd.service

[Service]
User=apache
Group=apache
Type=oneshot
Environment="PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/phabricator/bin/phd start
ExecStop=/opt/phabricator/bin/phd stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

I have created an upstart service for Ubuntu 14.04 LTS. Create a file /etc/init/phd.conf and save the following:

# Phabricator daemons init script
# You will need to change PHD_HOME to suit your installation
description     "Phabricator Daemon launcher"
author          "kaismh"

start on started mysql
stop on runlevel [!2345]

respawn
respawn limit 10 5
oom never

kill timeout 86400 #If it's given a stop order, this is how long it will take to stop.

setuid www-data
setgid www-data

env PHD_HOME=/opt/phabricator/phabricator/bin

pre-start script
    # Start phd
    exec $PHD_HOME/phd start
end script

post-stop script
    # Stop phd
    exec $PHD_HOME/phd stop
end script

You will need to adapt the script by changing user, PHD_HOME

Please be aware I have created an init script for CentOS based systems.

https://gist.github.com/jhogendorn/e7e58a3d071db6813be4

It would be useful for PHD to have some more programmatically friendly interfaces for scripting in this manner. Some difficulties I have encountered are primarily around detecting current state (<DEAD> pid files introduce a third state into something thats only really detectable as a boolean), as well as cleaning up out of date PID files (since they are not standard pid files I cannot rely on the os, and instead rely on the os to cleanly stop the service on shutdown. Obviously this is no good in recovering from a crash)

OS - Arch Linux

Hi all, I am trying to use a variation of the previously mentioned systemd unit files, but it will not work for me. It does work, if I try reloading the service after boot, which I find bizarre,

[Unit]
Description=phabricator-phd
After=network.target
Before=nginx.service php-fpm.service mysqld.service

[Service]
User=http
Group=http
Type=oneshot
Environment="PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/phacility/phabricator/bin/phd start
ExecStop=/opt/phacility/phabricator/bin/phd stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Thanks for any help you can provide.

I'm using this unit file, which works when I manually start it or restart it. However, if I do a cold boot of the system the unit fails and I have to ssh in and manually restart it.

[Unit]
Description=phabricator-phd
After=network.target nginx.service php-fpm.service mysqld.service

[Service]
User=phacility
Group=phacility
Type=oneshot
Environment="PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/phacility/phabricator/bin/phd start
ExecStop=/opt/phacility/phabricator/bin/phd stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

This is what I see in journalctl:

Feb 01 09:05:29 domain.tld systemd[1]: Starting phabricator-phd...
-- Subject: Unit phabricator-phd.service has begun start-up
-- Unit phabricator-phd.service has begun starting up.
Feb 01 09:05:30 domain.tld phd[1352]: Freeing active task leases...
Feb 01 09:05:30 domain.tld phd[1352]: [2016-02-01 14:05:30] EXCEPTION: (AphrontConnectionQueryException) Attempt to connect to phabricator@localhost failed with error #2002: No such file or directory. at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:328]
Feb 01 09:05:30 domain.tld phd[1352]: arcanist(head=stable, ref.master=57f6fb59d739, ref.stable=0553cb8d4118), phabricator(head=stable, ref.master=e4372e1276fd, ref.stable=5970d3c11473), phutil(head=stable, ref.master=f43291e99d36, ref.stable=9c472e7c9b64)
Feb 01 09:05:30 domain.tld phd[1352]: #0 AphrontBaseMySQLDatabaseConnection::throwConnectionException(integer, string, string, string) called at [<phutil>/src/aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php:72]
Feb 01 09:05:30 domain.tld phd[1352]: #1 AphrontMySQLiDatabaseConnection::connect() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:97]
Feb 01 09:05:30 domain.tld phd[1352]: #2 AphrontBaseMySQLDatabaseConnection::establishConnection() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:120]
Feb 01 09:05:30 domain.tld phd[1352]: #3 AphrontBaseMySQLDatabaseConnection::requireConnection() called at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:156]
Feb 01 09:05:30 domain.tld phd[1352]: #4 AphrontBaseMySQLDatabaseConnection::executeRawQuery(string) called at [<phutil>/src/xsprintf/queryfx.php:6]
Feb 01 09:05:30 domain.tld phd[1352]: #5 queryfx(AphrontMySQLiDatabaseConnection, string, string) called at [<phabricator>/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php:598]
Feb 01 09:05:30 domain.tld phd[1352]: #6 PhabricatorDaemonManagementWorkflow::freeActiveLeases() called at [<phabricator>/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php:353]
Feb 01 09:05:30 domain.tld phd[1352]: #7 PhabricatorDaemonManagementWorkflow::executeStartCommand(array) called at [<phabricator>/src/applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php:38]
Feb 01 09:05:30 domain.tld phd[1352]: #8 PhabricatorDaemonManagementStartWorkflow::execute(PhutilArgumentParser) called at [<phutil>/src/parser/argument/PhutilArgumentParser.php:408]
Feb 01 09:05:30 domain.tld phd[1352]: #9 PhutilArgumentParser::parseWorkflowsFull(array) called at [<phutil>/src/parser/argument/PhutilArgumentParser.php:301]
Feb 01 09:05:31 domain.tld phd[1352]: #10 PhutilArgumentParser::parseWorkflows(array) called at [<phabricator>/scripts/daemon/manage_daemons.php:23]
Feb 01 09:05:31 domain.tld systemd[1]: phabricator-phd.service: Main process exited, code=exited, status=255/n/a
Feb 01 09:05:31 domain.tld systemd[1]: Failed to start phabricator-phd.
-- Subject: Unit phabricator-phd.service has failed
-- Unit phabricator-phd.service has failed.
Feb 01 09:05:31 domain.tld systemd[1]: phabricator-phd.service: Unit entered failed state.
Feb 01 09:05:31 domain.tld audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=phabricator-phd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'
Feb 01 09:05:31 domain.tld systemd[1]: phabricator-phd.service: Failed with result 'exit-code'.

Please advise.

@sinayion don't start the phd service before mysql. The daemons need the database to be active.
I'd start phd after http and mysql are up and running.

I changed the unit file to this:

[Unit]
Description=phabricator-phd
After=network.target maridb.service

[Service]
User=phacility
Group=phacility
Type=oneshot
Environment="PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/phacility/phabricator/bin/phd start
ExecStop=/opt/phacility/phabricator/bin/phd stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

But on a clean boot it still fails with the above error.

I have created an upstart service for Ubuntu 14.04 LTS. Create a file /etc/init/phd.conf and save the following:

Thanks for providing this. For people who'd like a SysV version of this until the related ticket is resolved, I've found a great template service script at https://github.com/fhd/init-script-template - it's child's play to tweak the available settings and utilise this for phd.

@sinayion don't start the phd service before mysql. The daemons need the database to be active.
I'd start phd after http and mysql are up and running.

You rock! After reading your comment, I can't believe how silly I was. It now works on boot! :D

I have created an upstart service for Ubuntu 14.04 LTS. Create a file /etc/init/phd.conf and save the following:

I was not able to use this script in any of my installations, it always causes bootup/shutdown to hang and does not properly start the phd daemons. For some reason, phd for me has been very difficult to get up and running with upstart scripts. Whatever I do, calling service phd start always results in just a hang. If anyone has any insight into how I can do this, would be greatly appreciated. I'm running Ubuntu.

I've tried with expect fork and expect daemon, to no avail.

An even simpler script below, works now on my Fedora 24 server. Just make sure for your distribution, that the correct database (mysql/mariadb/etc.) service is edited, as well as the rest of the info.

[Unit]
Description=Phabricator Daemons
After=syslog.target network.target mariadb.service

[Service]
Type=forking
User=nginx
Group=nginx
ExecStart=/opt/phacility/phabricator/bin/phd start
ExecStop=/opt/phacility/phabricator/bin/phd stop

[Install]
WantedBy=multi-user.target

If this fails again, carefully check your "journalctl -xe" logs. You might need to edit the permissions of folders, for the user that you want the daemons to run as.

The real working example

[Unit]
Description=phd
After=network.target 
Requires=network.target

[Service]
Type=forking
ExecStart=/usr/bin/sudo -u vcs-user  /opt/phabricator/bin/phd start
ExecStop=/usr/bin/sudo -u vcs-user /opt/phabricator/bin/phd stop
Restart=always
RestartSec=10
StartLimitInterval=0
StartLimitBurst=0
[Install]
WantedBy=multi-user.target

The real working example

[…]
ExecStart=/usr/bin/sudo -u vcs-user  /opt/phabricator/bin/phd start
ExecStop=/usr/bin/sudo -u vcs-user /opt/phabricator/bin/phd stop
[…]

Using sudo in a service unit is strongly discouraged - use a service unit's User= and Group= directives instead.

@epriestley was just curious if any of the "Real Working Examples" could be brought into the resource folder in phabricator, this information is super useful and helps complete the product.

No, we don't want to bring anything upstream if we don't support or maintain it.