PHABRICATI DIEM, PVNC

Aside

the whys

I’ve planned to play with one or another source code management platform since quite a time, but only recently have found enough time to actually try it.

My criteria were very far from professional: I was looking for a project that:

  • is functional enough that using it instead of github won’t be too much of a pain,
  • is easy enough to install (from zero to functional installation in five hours time tops, and that including reading the documentation for the first time),
  • runs well on apache (because I already have a reasonably well-configured apache instance running),
  • works with mysql (like with the apache, I already have well-tuned mysql instance),
  • last but not least, relies on packaged software only (because I am lazy)

That unfortunately ruled out redmine and all ruby-on-rails-based github clones out there, including the otherwise appealing gitorious. The most interesting contender from the python side of the world – rhodecode – switched from free software to closed source, and the only other name I remembered was phabricator.

I’ve heard about the project for the first time during one of Facebook Dublin’s Infrastructure Open House meetings and it definitely piqued my interest then – it is, basically, an integrated software engineering platform that’s used by Facebook internally to manage all their code. It is also an open source project available under Apache licence. Written in well-managed PHP, it runs – or is advertised to run – on almost everything.

the hows

Upstream guides for both installation and setup are quite good, notes below handle the differences.

difference #1: apache + mod_fcgid + worker mpm

I have mod_fcgid configured to use a wrapper script from a directory that’s mapped to the /fcgi-bin alias:

<IfModule mod_fcgid.c>
    ⋮
    AddType application/x-php         php phtml php3
    AddType application/x-php-source  phps
    AddHandler php-fcgid .php
    Action php-fcgid /fcgi-bin/php-fcgi-wrapper
    Alias /fcgi-bin/ /var/www/fcgi-bin.d/php5-default/

    <FilesMatch ".+\.ph(p[345]?|t|tml)$">
      SetHandler php-fcgid
    </FilesMatch>

    <Location /fcgi-bin/>
        SetHandler fcgid-script
        Options +ExecCGI
    </Location>
    ⋮
</IfModule>

For Phabricator to work with this configuration you have to add the first rewrite rule, to make sure that the fcgi invocations will not be touched – if the path to the fcgi handler is not whitelisted, the last rule with its greedy regex will break the php fcgi execution.

<VirtualHost>
    ⋮
    RewriteRule ^/fcgi-bin            -                       [L]
    RewriteRule ^/rsrc/(.*)           -                       [L,QSA]
    RewriteRule ^/favicon.ico         -                       [L,QSA]
    RewriteRule ^(.*)$                /index.php?__path__=$1  [B,L,QSA]
    ⋮
</VirtualHost>

difference#2: managing phd through init daemon

I’m using the following service file to keep the phd services up:

[Unit]
Description=the phabricator daemon service
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
WorkingDirectory=/srv/blueprint/phabricator/bin
ExecStart=/srv/blueprint/phabricator/bin/phd start
ExecStop=/srv/blueprint/phabricator/bin/phd stop
Restart=always
User=phd
Group=phd

[Install]
WantedBy=multi-user.target

difference#3: make diffusion’s ssh service listen on a custom port

I’m using ‘vcs’ as the user name and decided to run customised ssh service listening on ports 22 and 2401 on a dedicated IP to manage the ssh-based VCS operations. (The openssh-server package from wheezy backports is needed for the AuthorizedKeysCommand support.)

/etc/systemd/system/phabricator-ssh.service:

[Unit]
Description=phabricator ssh service
After=network.target auditd.service phd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-/etc/default/phabricator
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=phabricator-sshd.service

/etc/default/phabricator-ssh:

# (line breaks for clarity)
SSHD_OPTS="-f /etc/ssh/sshd_config_phabricator \
           -h /etc/ssh/ssh_host_dsa_key \
           -h /etc/ssh/ssh_host_rsa_key \
           -h /etc/ssh/ssh_host_ecdsa_key"

/etc/ssh/sshd_config_phabricator:

# NOTE: You must have OpenSSHD 6.2 or newer; support for AuthorizedKeysCommand
# was added in this version.

AuthorizedKeysCommandUser vcs
AuthorizedKeysCommand /usr/local/lib/phabricator/bin/ssh-hook
AllowUsers vcs

# You may need to tweak these options, but mostly they just turn off everything
# dangerous.

ListenAddress 144.76.160.154:22
ListenAddress 144.76.160.154:2401
ListenAddress [2a01:4f8:200:20e2:1::c]:22
ListenAddress [2a01:4f8:200:20e2:1::c]:2401
Protocol 2
PermitRootLogin no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
PrintLastLog no
PasswordAuthentication no
AuthorizedKeysFile none

PidFile /var/run/phabricator-sshd.pid

the results

Fully featured phabricator installation, with git, mercurial and svn available through https and ssh protocols, project/task management, wiki, pastebin clone etc., with LDAP and github account integration.

Not too bad for a Sunday afternoon project, if I may say so myself.