HHVM (HipHop) with ISPConfig

Discussion in 'Plugins/Modules/Addons' started by ItsDom, Mar 15, 2014.

  1. ItsDom

    ItsDom New Member

    Hi.

    HHVM is HipHop VM. It was written by Facebook and "it works by converting PHP code into high level bytecode(an intermediate language) this bytecode is the translated into machine code dynamically at runtime by a JIT (Just-In-Time) compiler." (http://coderoncode.com/2013/07/24/introduction-hhvm.html). It does all this behind the scenes so in terms of usage and development, it's the same as PHP once setup, but a lot faster.

    It was originally designed as a full stack including webserver, but recently, they released a version support to run with another web server, via fastCGI

    I found that the prebuilt version on the github for CentOS (https://github.com/facebook/hhvm/wiki/Prebuilt-hhvm-2.3-packages-for-centos-6.x) was problematic. It required a newer version of binutils for gcc than was easily available for CentOS 6.5.

    Instead I used the version available in the hop.in repo using instructions available here: http://nareshv.blogspot.co.uk/2013/12/installing-hhvm-23-on-centos-65.html

    You can then start it running with hhvm --mode daemon -vServer.Type=fastcgi -vServer.Port=8999

    I used port 8999 to avoid conflicting with php-fpm.

    To set it running, I then added the following nginx directive for the domain on which to run it:

    Code:
    location ~ \.php$ {
        fastcgi_keep_conn on;
        fastcgi_pass 127.0.0.1:8999;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
      }
    And it works. I've been playing with fat-free framework and the site I've been making, the difference between the start point and end point of the script with php-fpm was typically around 50ms - 75ms, with HHVM it's down to 10 - 20ms.

    However, this runs everything as root, which is a big security issue if I were running on an external production server. You can specify which user to run HHVM with when you start the daemon with with --user.

    Does anyone have any advice on the most efficient way to have all sites running HHVM, but all executing with the correct user for the site, other than having multiple daemon instances running, 1 for each user?



    Thanks in advanced.

    Dom.
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    I guess there is no other solution, when hhvm does not support contect switching. e.g. php-fpm runs a own daemon for each website as well. so that the normal way in doing it.
     
  3. moglia

    moglia New Member

    Adding HHVM support for ISPConfig 3.0.5.3 on Ubuntu 12.04

    This is a workaround for adding HHVM support for ISPConfig, any update to ISPConfig will remove these changes and might break the installation.

    This workaround is tested but is NOT guaranted to work, so please try it locally before applying to your server.

    Before proceeding, if you do not have ISPConfig install it as described here : http://www.howtoforge.com/perfect-server-ubuntu-12.04-lts-apache2-bind-dovecot-ispconfig-3

    1 – Checking/installinig PHP5-FPM

    1st of all check that PHP5-FPM and suexec are installed on your server, if not you can do this AFTER installing ISPConfig

    Code:
        
    apt-get install apache2-mpm-worker apache2-suexec php5-cgi libapache2 mod-fcgid 
    a2enmod fcgid
    a2enmod suexec
    


    2 – Install HHVM

    Code:
    sudo add-apt-repository ppa:mapnik/boost
        wget -O – http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
        echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list
        sudo apt-get update
        sudo apt-get install hhvm




    3 – ISPConfig Modifications

    in /interface/web/sites/form/web_domain.tform.php

    Add :

    Code:
        'hhvm' => 'HHVM Over PHP-FPM'
    
    In the 'value' sub-array of this block :
    
              'php' => array (
                    'datatype'    => 'VARCHAR',
                    'formtype'    => 'SELECT',
                    'default'    => 'fast-cgi',
                    'valuelimit' => 'client:web_php_options',
                    'value'        => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM'),
                    'searchable' => 2
                )
    
    so the line will look like :
    
    'value'        => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM Over PHP-FPM'),
    

    4 – in /server/conf/vhost.conf.master



    Code:
    after :
    
        after <tmpl_if name='php' op='==' value='php-fpm'> <IfModule mod_fastcgi.c>
    
    Add :
    
        <tmpl_if name='php' op='==' value='hhvm'>
            <IfModule mod_fastcgi.c>
                <Directory {tmpl_var name='document_root'}/cgi-bin>
                    Order allow,deny
                    Allow from all
                </Directory>
                        AddHandler php5-fcgi .php
                        Action php5-fcgi /php5-fcgi
                Alias /php5-fcgi {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'}
                
                <tmpl_if name='use_tcp'>
                            FastCgiExternalServer {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} -idle-timeout 300 -host 127.0.0.1:<tmpl_var name='hhvm_port'> -pass-header Authorization
                </tmpl_if>
                <tmpl_if name='use_socket'>
                            FastCgiExternalServer {tmpl_var name='document_root'}/cgi-bin/php5-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} -idle-timeout 300 -socket <tmpl_var name='hhvm_socket'> -pass-header Authorization
                </tmpl_if>
            </IfModule>
        </tmpl_if>


    Change this :

    Code:
       <tmpl_if name='php' op='==' value='php-fpm'>
            DocumentRoot <tmpl_var name='web_document_root'>
        </tmpl_else>
            DocumentRoot <tmpl_var name='web_document_root_www'>
        </tmpl_if>
    into this :

    Code:
     <tmpl_if name='php' op='==' value='php-fpm'>
            DocumentRoot <tmpl_var name='web_document_root'>
        </tmpl_else>
            <tmpl_if name='php' op='==' value='hhvm'>
                DocumentRoot <tmpl_var name='web_document_root'>
            </tmpl_else>
                DocumentRoot <tmpl_var name='web_document_root_www'>
            </tmpl_if>
        </tmpl_if>
    

    5 – server/plugins-avaialble/apache2_plugin.inc.php



    add this method inside the class :

    PHP:
        function hhvm_upstart($web_config){
            global 
    $app,$conf;
            
    // create upstart script
                
                //clear service_pool in mysql
                
                
    $script_content '#!/bin/bash

        mysql –user="'
    .$conf['db_user'].’” –password=”‘.$conf['db_password'].’” –database=”‘.$conf['db_database'].'" –execute="DELETE FROM service_pool"'."\n\n";
                
                
    $upstart_services $app->db->queryAllRecords("SELECT * FROM web_domain WHERE type='vhost' and php = 'hhvm'");
                
    file_put_contents('/tmp/isp/t.txt'print_r($upstart_services,true));
                if(
    is_array($upstart_services) && !empty($upstart_services)){
                    foreach (
    $upstart_services as $service){
                        
    $script_content .= 'cd '.$service['document_root']."\n";
                        
                        
    $port '2' . ($web_config['php_fpm_start_port'] + $service['domain_id'– 1); // get the hhvm port
                        
    $script_content .= 'hhvm –mode server -vServer.Type=fastcgi -vServer.Port=' $port ' > /dev/null 2>&1 & PID=$!; '."\n";
                        
    $script_content .= 'mysql –user="'.$conf['db_user'].’” –password=”‘.$conf['db_password'].’” –database=”‘.$conf['db_database'].’” –execute=”INSERT INTO service_pool (service_type,server_id,service_pidVALUES (\’hhvm\’ ,\.$service['domain_id'].'\', \'$PID\')"'."\n";
                        
                    }
                }
                
                
    file_put_contents('/etc/init.d/hhvm_ispconfig.sh'$script_content);
                
    exec('chmod +x /etc/init.d/hhvm_ispconfig.sh');
                
    exec('update-rc.d hhvm_ispconfig.sh defaults');
        }


    add this line to the end of update() method :

    PHP:
     $this->hhvm_upstart($web_config);



    After :

    PHP:
      $fpm_socket $socket_dir.$pool_name.'.sock';
        
    $tpl->setVar('fpm_socket'$fpm_socket);
        
    $tpl->setVar('fpm_port'$web_config['php_fpm_start_port'] + $data['new']['domain_id'– 1);
    Add :

    PHP:
     $hhvm_socket $socket_dir.$pool_name.'.hhvm.sock';
        
    $tpl->setVar('hhvm_socket'$hhvm_socket);
        
    $tpl->setVar('hhvm_port''2' . ($web_config['php_fpm_start_port'] + $data['new']['domain_id'– 1));




    Replace :

    PHP:
     if($data['new']['php'] == 'php-fpm'){
    With :

    PHP:
      if($data['new']['php'] == ‘php-fpm’ || $data['new']['php'] == 'hhvm'){




    Replace :

    PHP:
     if(trim($data['old']['fastcgi_php_version']) != ” && $data['old']['php'] == 'php-fpm'){
    With :

    PHP:
       if(trim($data['old']['fastcgi_php_version']) != ” && ($data['old']['php'] == ‘php-fpm’  || $data['new']['php'] == 'hhvm')){


    Replace :

    PHP:
      if(trim($data['old']['fastcgi_php_version']) != ” && $data['old']['php'] == 'php-fpm'){
    With :

    PHP:
     if(trim($data['old']['fastcgi_php_version']) != ” && ($data['old']['php'] == ‘php-fpm’  || $data['new']['php'] == 'hhvm')){


    in the end of method "php_fpm_pool_update" add :

    //Remove all hhvm instances
    PHP:
      $old_services $app->db->queryAllRecords("SELECT * FROM service_pool WHERE service_type = 'hhvm' AND server_id = '".$data['new']['domain_id']."'");
            if(
    is_array($old_services) && !empty($old_services)){
                foreach (
    $old_services as $old_service){
                
    exec("kill -9 ".$old_service['service_pid']);
                }
            }
            
    $app->db->query("DELETE FROM service_pool WHERE service_type = 'hhvm' AND server_id = '".$data['new']['domain_id']."'");

            
    $tmpCurDir __DIR__// store the current cirectory
            
    chdir($data['new']['document_root']); // change to the document root as HHVM needs to be run from there

            // start a fresh hhvm instance
            
    $port '2' . ($web_config['php_fpm_start_port'] + $data['new']['domain_id'– 1); // get the hhvm port
            
    $command =  'hhvm –mode server -vServer.Type=fastcgi -vServer.Port=' $port ' > /dev/null 2>&1 & echo $!; ';
            
    $pid exec($command$output);

            
    $app->db->query("INSERT INTO service_pool (service_type,server_id,service_pid) VALUES ('hhvm' ,'".$data['new']['domain_id']."', '".$pid."')");


    6 – in /interface/web/sites/templates/web_domain_edit.htm



    Replace :

    PHP:
      if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm'){
    With :

    PHP:
     if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm' || jQuery('#php').val() == 'hhvm'){


    Replace :

    PHP:
       if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm'){
    With :

    PHP:
      if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm' || jQuery(this).val() == 'hhvm'){

    7 – Create the following table in the ISPConfig database :

    Code:
      CREATE TABLE IF NOT EXISTS `service_pool` (
          `service_id` int(11) NOT NULL AUTO_INCREMENT,
          `service_type` varchar(32) NOT NULL,
          `service_pid` int(11) NOT NULL,
          `server_id` int(11) NOT NULL,
          PRIMARY KEY (`service_id`),
          KEY `service_type` (`service_type`),
          KEY `server_id` (`server_id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
    

    Hopy this will help you out guys ! Enjoy !
     
  4. Ovidiu

    Ovidiu Active Member

    Is there any work being done on making ISPCFG3 support hhvm? I'm playing with it locally on a 1-website server and was thinking this could be so awesome if ISPCFG3 would support it at some stage..
     
  5. till

    till Super Moderator Staff Member ISPConfig Developer

    It is planned to implement it. If you like to help us and want to speed this up, make a fork of ispconfig master branch on our gitlab server, implement the function and make a merge request against the master branch.

    Our gitlab server can be found here:

    http://git.ispconfig.org
     
    Last edited: Jan 7, 2015
  6. ChristophK

    ChristophK New Member

    @moglia

    Thanks for your time to write that tutorial. But there are a lot of errors in the code probably from a typographical beautifier or something like that.

    a lot of wrong quotation marks
    "" -> “*”
    '' -> ‘*’
    `` -> ‘*’

    A lot of the minuses - are the long mathematical minus and not the hyphen
    - -> –
     
  7. moglia

    moglia New Member

    HHVM Testings

    Till this tutorial is not mine but i can try put it on ispconfig repos. I do some tests with hip-hop hhvm somethings not work but will be a good option near future. If have more interest on it i can spend a time for study it and adtional implements. I have access to SVN in time i need update some translations to my local language. :)
     
  8. till

    till Super Moderator Staff Member ISPConfig Developer

    @moglia: It would be great if you could add it to our dev version. We switcehd from SVN to GIT, the new server is here:

    http://git.ispconfig.org/

    please register for a git account on that server, then fork the master branch there to get your own working copy.
     
  9. Croydon

    Croydon ISPConfig Developer ISPConfig Developer

  10. NocZone

    NocZone New Member

    You could have at least mentioned the source http://blog.noczone.com/?p=102 :)
     
  11. Croydon

    Croydon ISPConfig Developer ISPConfig Developer

    Patch available

    So I have completed a first integration of hhvm.
    I used a different approach than proposed here for various reasons.
    The patch is compatible with 3.0.5.4 as far as I have tested it, but it is considered unofficial and EXPERIMENTAL!
    So use it at your own risk.

    Prerequisites
    This was only tested on debian wheezy so far, although it should work on ubuntu and debian squeeze, too.

    Install hhvm on your server like explained here:
    https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Debian-7
    https://github.com/facebook/hhvm/wiki/Prebuilt-packages-on-Ubuntu-14.04
    https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Ubuntu-13.10
    https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Ubuntu-12.04

    Do not follow the various fastcgi installation howtos that say to run the fastcgi installer of hhvm!

    Stop hhvm if it was automatically started and remove the startup script:
    Code:
    service hhvm stop
    update-rc.d hhvm remove
    Install patch
    Download the attached patch file to your server.

    Test if there are any problems with applying the patch
    Code:
    cd /usr/local/ispconfig/
    patch -p0 --dry-run < /path/to/downloaded/3054_hhvm.txt
    
    Messages like
    Hunk #1 succeeded at 1642 (offset -2 lines).
    are ok.
    If it says something like "rejected or saving rejects to xxx" DO NOT continue.

    If everything is ok, continue and apply the patch:
    Code:
    cd /usr/local/ispconfig/
    patch -p0 < /path/to/downloaded/3054_hhvm.txt
    
    Use HHVM
    You can now (or at least you should be able to) mark the checkbox "HHVM" in the valid client php modes (client and reseller limits / client templates).
    In the website settings there should be a new PHP mode "HHVM" available.
    Choose it, save, cross your fingers and wait ;)

    Please report any bugs you find. Thanks.
     

    Attached Files:

    Last edited: Apr 30, 2014
  12. moglia

    moglia New Member

    More about HHVM

    To anyone try it hhvm from packages v 2.X not good for prod enviroments. I can run anyting on it. I get from repos and recompiled binary into version 3 betas i run some scripts like phpmyadmin and need tests more scripts for evaluate more.
     
  13. Croydon

    Croydon ISPConfig Developer ISPConfig Developer

    The version in debian wheezy repo is 3.0.1. Didn't test version 2.x of hhvm.
     
  14. moglia

    moglia New Member

    Maybe updated last time i used.
    I´m using this apt lines:

    Code:
    deb http://dl.hhvm.com/debian wheezy main
    Dkpg info:

    Code:
    root@alfa:/# dpkg -l | grep hhvm
    ii  hhvm                               2.4.2~wheezy                  amd64        HHVM virtual machine, runtime, and JIT for the PHP language
    ii  hhvm-fastcgi                       2.3.2                         all          The package provides FastCGI support for HHVM. HHVM is a high-performance just-in-time compiled PHP runtime. FastCGI is a protocol that allows language interpreters to run behind web servers.
    
    When i do update .... The following packages have been kept back: hhvm i´m not installing hhvm-nightly
     
  15. Croydon

    Croydon ISPConfig Developer ISPConfig Developer

    I think you have to do "apt-get install hhvm"
    An standard update might not work as there is no hhvm-fastcgi package anymore in 3.x (it is in the hhvm already) so your update is kept back because it would require removal of packages.
     
  16. rober

    rober New Member

    Hi Croydon. i have a server in rackspace with ubuntu and ISPCONFIG 3.0.5.4p1 . and i want try out hhvm 3.1 over it.

    Do can i use HHVM with ISPCONFIG right now? how can update my installation?

    tks for help
     
  17. JanThiel

    JanThiel Member

    Hi Croydon,

    just ran through your guide and ... Thank you very much! It worked like a charm and now runs perfectly!

    I am running on latest Debian (Setup after perfect server guide, with Dot DEB Repos and on nginx).

    Figured out one issue with the 3.0.5.4p3 access rights "admin_allow_server_services". I now get with my user (has Admin rights) an error that I miss the respective access rights when trying to configure most thing under the "System" tab. Thats the only issue found so far.

    I would love to see HHVM Support in Core!

    Brgds and thank you very much.

    Jan
     
  18. durchd8.de

    durchd8.de Member

    It makes no real sense right now to implement HHVM like php. The user rights management is low on HHVM development priority list - very low.

    That being said, it makes sense to implement HHVM as an option:
    1. for virtual servers in their template ofc (yet it needs a lot of RAM).
    2. for single servers running for one Client only (set HHVM user to Client user).
    3. HHVM only server for one CMS or application, where the CMS/application performs the rights management.
    4. HHVM only server dedicated to one CMS/application without Client access to the files (risky since you can get around that in most cases).

    An ISPConfig server running for multiple Clients/sites "normally", where HHVM replaces php is imho crazy - even if you get security right, one Client can access all other Client resources via HHVM. Sounds more like suicide.

    Still should you do despite above advice, consider at least restricting access, while making HHVM run for all Clients by setting ACLs with SGID on the webroot offering r/w on all files/directories for user accounts.
     
  19. Croydon

    Croydon ISPConfig Developer ISPConfig Developer

    This is true for hhvm server but not for hhvm as fastCGI.
     
  20. durchd8.de

    durchd8.de Member

    Correct - that implementation is totally out of question for me, so I actually didnt even think about it ;)
     

Share This Page