Install HHVM, Nginx and, Magento 2 on CentOS 7 - PPC64/hhvm GitHub Wiki

#Install HHVM, Nginx and, Magento 2 on CentOS 7

Introduction

Magento is an open source e-commerce software and content management system for e-commerce websites based on the PHP Zend Framework. It uses MySQL or MariaDB as database backend. This install guide shows how to install HHVM* and Magento 2 with Nginx, and MariaDB as the database. This guide uses CentOS 7.2 as server operating system on POWER8 (ppc64el).

*Note: HHVM is not officially supported on CentOS.

Prerequisites

First log as sudo and then install epel and update:

sudo su
yum install -y epel-release
yum update -y

Install build tools:

yum install autoconf automake binutils bison flex gcc gcc-c++ gettext libtool make - y

Alternatively you can install 'Development Tools' which have all those packages:

yum groupinstall 'Development Tools' -y

Then install php/hhvm dependencies:

 yum install git psmisc {binutils,boost,jemalloc,numactl}-devel \
 {ImageMagick,sqlite,tbb,bzip2,openldap,readline,elfutils-libelf,gmp,lz4,pcre, httpd, gmp, aspell, freetype}-devel \ 
 lib{xslt,event,yaml,vpx,png,zip,icu,mcrypt,memcached,cap,dwarf, cu}-devel \ 
 {unixODBC,expat,mariadb}-devel lib{edit,curl,xml2,xslt, Xpm}-devel gperf \ 
 enca libjpeg-turbo-devel openssl-devel t1lib-devel libtidy-devel \ 
 {fastlz,double-conversion,re2}-devel oniguruma-devel -y

Step 1 - Build dependencies

Some dependencies needs to be build from source. Package versions won't work:

Build and install CMake

CMake 2.8.12 or higher is required to install HHVM but CentOS 7 comes with 2.7.

Download CMake 3:

wget https://cmake.org/files/v3.7/cmake-3.7.0.tar.gz

Then:

./bootstrap --prefix=/usr/local

It will install cmake at /usr/local but you can choose another place to install. After bootstrap finish, run:

make && make install

Include cmake installation path:

export PATH=/usr/local/bin:$PATH

Build and install PHP 5.6

CentOS 7 comes with php 5.4 with is not supported by Composer anymore and you give us a error requires php >=5.4.0 when try to install Magento. PPC64el doesn't have a remi repository so we need to build from source. Download PHP 5.6:

 wget -O php-5.6.27.tar.bz2 http://br1.php.net/get/php-5.6.27.tar.bz2/from/this/mirror

Extract PHP 5.6

tar -jxf php-5.6.27.tar.bz2

Now go to the source folder:

cd php-5.6.27/

And run:

./configure \
    --with-libdir=lib64 \
    --prefix=/usr/local \
    --with-layout=PHP \
    --with-pear \
    --enable-calendar \
    --enable-bcmath \
    --with-gmp \
    --enable-exif \
    --with-mcrypt \
    --with-mhash \
    --with-zlib \
    --with-bz2 \
    --enable-zip \
    --enable-ftp \
    --enable-mbstring \
    --with-iconv \
    --enable-intl \
    --with-icu-dir=/usr \
    --with-gettext \
    --with-pspell \
    --enable-sockets \
    --with-openssl \
    --with-curl \
    --with-gd \
    --enable-gd-native-ttf \
    --with-jpeg-dir=/usr \
    --with-png-dir=/usr \
    --with-zlib-dir=/usr \
    --with-xpm-dir=/usr \
    --with-vpx-dir=/usr \
    --with-freetype-dir=/usr \
    --with-t1lib=/usr \
    --with-libxml-dir=/usr \
    --with-mysql=mysqlnd \
    --with-mysqli=mysqlnd \
    --with-pdo-mysql=mysqlnd \
    --enable-soap \
    --with-xmlrpc \
    --with-xsl \
    --with-tidy=/usr \
    --with-readline \
    --enable-pcntl \
    --enable-sysvshm \
    --enable-sysvmsg \
    --enable-shmop

Now build and install:

make && make install

Build and install libglog

Google logging module. CentOS7 doesn't come with this package.

wget https://github.com/google/glog/archive/v0.3.4.tar.gz

Now run:

./configure --prefix=/usr/local

And then install:

make && make install

Finally export the path:

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

Automake issue

Glog needs automake 1.14 and CentOS 7 has automake 1.13 is installed so you get the following error:

[root@test glog]# make && make install
CDPATH="${ZSH_VERSION+.}:" && cd . && aclocal-1.14 -I m4
/bin/sh: aclocal-1.14: command not found
/bin/sh: line 4: automake-1.14: command not found

You can download and install automake/autoconf tools or workaround it by trick glog make:

ln -s /usr/bin/aclocal /usr/bin/aclocal-1.14
ln -s /usr/bin/automake /usr/bin/automake-1.14

After that if you get the following error:

parallel-tests: error: required file './test-driver' not found

Just run:

automake --add-missing

And then make install again.

Build and installl Boost 1.58

CentOS 7 comes with boost 1.53 but if you try build HHVM with this version of boost you will get the following error:

 CMake Error at /usr/local/share/cmake-3.7/Modules/FindBoost.cmake:1793 (message):
  Unable to find the requested Boost libraries.
  Boost version: 1.53.0
  Boost include path: /usr/include
  Could not find the following Boost libraries:
  boost_contex

First download boost 1.58:

 wget -O boost_1_58_0.tar.bz2  http://downloads.sourceforge.net/project/boost/boost/1.58.0/boost_1_58_0.tar.bz2?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.58.0%2F&ts=1479836204&use_mirror=ufpr

Now run:

./bootstrap.sh --prefix=/usr/local --with-toolset=gcc

and then:

./b2
./b2 install

*Note:* do not use boost > 1.59 as you may get a build error see https://github.com/facebook/folly/issues/413 for more details.

Build and install jmalloc

Jemalloc is a general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. There's no package for jmalloc on CentOS 7.

Download and extract jmalloc:

wget http://www.canonware.com/download/jemalloc/jemalloc-3.6.0.tar.bz2 &&
tar jxvf jemalloc-3.6.0.tar.bz2 && cd jemalloc-3.6.0

Then run:

./configure && make && make install

Build and install OCaml

In order to use hack you need to install ocaml. Ubuntu 16.04 doesn't have a .deb package so you need to install it from the repository:

Clone the repository and enter the directory.

# git clone https://github.com/ocaml/ocaml.git
# cd ocaml

Run configure script. By default it will install be installed on /usr/local but you can install it at another location using prefix option:

# ./configure --prefix /usr

Run make (Important: do not run parallel instances (-j parameter) as the build may fail):

# make world.opt

There is a test suite. And yes, it is 'make tests', not 'test' or 'check'. Does not work with parallel jobs.

# make tests

Now you can install.

# make install

In order to compile hack typechecker you need to compile and install ocamlbuild and the native compiler. OCamlbuild was distributed as part of the OCaml distribution for OCaml versions between 3.10.0 and 4.02.3. Starting from OCaml 4.03, it is now released separately.

First clone the repository:

git clone https://github.com/ocaml/ocamlbuild

and then configure:

make configure OCAML_NATIVE=true

and finally install:

make && make install

Step 2 - Install Nginx

yum install nginx -y

Verify that nginx has been installed properly by checking the port:

netstat -plntu | grep 80

Note: You may have a error 'command not found' when try to run netstat on CentOS 7. Just install net-tools:

yum install net-tools

##Step 3 - Install MariaDB

yum install mariadb-server mariadb-client -y

Set MariaDB user/password:

mysqladmin -u root password mypassword

Enter the password when prompted:

Mysql password prompt

Then connect to the MariaDB shell (with command mysql) with your root password, create a database with the name magentodb and a user magentouser with the password magentouser@.

Login to the MariaDB shell:

mysql -u root -p

On MariaDB shell run the following command:

CREATE DATABASE magentodb;
CREATE USER magentouser@localhost IDENTIFIED BY 'magentouser@';
GRANT ALL PRIVILEGES ON magentodb.* TO magentouser@localhost IDENTIFIED BY 'magentouser@';
FLUSH PRIVILEGES;
\q

MariaDB magento2 database and user configuration

Database was created and configured.


ATTENTION

If you got a Access denied for user 'root'@'localhost error when try to access MariaDB you can try to reset root password:

sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
exit;

Step 4 - Install Magento 2

Install Composer

Go to a /tmp directory, download the composer installer file with curl and run it to install composer:

cd /tmp
curl -sS https://getcomposer.org/installer | php

Move the file composer.phar file to the bin directory of your server and rename it to composer so it can be executed easily:

mv composer.phar /usr/bin/composer

Verify that composer is working:

composer -v

###Download and extract Magento2

Go to the web directory /var/www/ and download Magento from Github, then unpack:

 cd /var/www/
 wget https://github.com/magento/magento2/archive/2.0.7.tar.gz
 tar -xzvf 2.0.7.tar.gz
 mv magento2-2.0.7/ magento2/

Now you have to configure a Magento Key. This account is required to use Magento and the Magento composer store. First you need to create the account at Magento site by click in Register button:

Figure 3 - Creating a login at Magento

After fill the fields and agree with terms you have to access the account and set a pair of Secure Keys. Just type your user name and generate the pair of keys it will be required when installing Magento:

Figure 4 - Create a pair of Secure Keys

Now you can install Magento. Go to directory /var/www/magento2 and run:

cd /var/www/magento2/
composer install -v

You will be asked for the Magento authentication, use the public key as username and the private key for the password:

Figure 5 - Magento authentication

Step 5 - Build and Install HHVM

HHVM do not have a package for CentOS so it will be need to build from source.

Getting HHVM source:

 git clone -b next git://github.com/PPC64/hhvm.git --depth=1
 export CMAKE_PREFIX_PATH=`pwd`

Now download submodules:

 cd hhvm
 git submodule update --init --recursive

Then run cmake:

 cmake -DCMAKE_BUILD_TYPE=Release -DBOOST_ROOT=/usr/local/include/boost/ -DLIBGLOG_INCLUDE_DIR=/usr/local/include/glog/ -DLIBGLOG_LIBRARY=/usr/local/lib/libglog.so .

Note: the options may vary depends where do you install the dependencies that you build from source (Step 2).

The run make (replace n by the number of cores available):

make -jn

and then:

make install

Create a php.ini file

HHVM try to get some configurations (like if JIT, typechecker is enable or not) on a ini file. By default HHVM search those configurations on a php.ini file at /etc/hhvm . So create this file php.ini and include the following content:

; php options
session.save_handler = files
session.save_path = /var/lib/hhvm/session
session.gc_maxlifetime = 1440
; hhvm specific
hhvm.log.level = Error
hhvm.log.always_log_unhandled_exceptions = true
hhvm.log.runtime_error_reporting_level = 8191
hhvm.mysql.typed_results = false
hhvm.jit = 0

Setup HHVM to work with fastcgi

Create a file '/etc/hhvm/server.ini' and edit the file to look's like bellow:

; php options

pid = /var/run/hhvm/pid

; hhvm specific 

hhvm.server.port = 9000
hhvm.server.type = fastcgi
hhvm.server.default_document = index.php
hhvm.log.use_log_file = true
hhvm.log.file = /var/log/hhvm/error.log
hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc

This will run HHVM server at port 9000 using fastcgi.

Install HHVM as a service

To have HHVM start as a daemon you need to create an HHVM service. Create a file named hhvm.service at /usr/lib/systemd/system. This will allow you to start HHVM as a daemon by issuing service start and stop commands and enable HHVM to be run on boot:

[Unit]
Description=HipHop Virtual Machine

[Service]
ExecStart=/usr/local/bin/hhvm -m daemon -u nginx -c /etc/hhvm/server.ini
ExecStop=rm /var/run/hhvm.pid
PIDFile=/var/run/hhvm.pid

[Install]
WantedBy=multi-user.target

Now you can start HHVM daemon with:

systemctl start hhvm

Optionally you can enable it at boot:

systemctl enable hhvm

CentOS bug

If you try to run a php program on HHVM you may got a segmentation fault error or a assert error if you build HHVM in debug mode:

Assertion failure: /home/hhvm-3.15.0/hphp/runtime/vm/jit/fixup.cpp:108: void HPHP::jit::FixupMap::fixupWork(HPHP::ExecutionContext*, HPHP::ActRec*) const: assertion `nextRbp && nextRbp != rbp && "Missing fixup for native call"' failed.

This is a new problem which affects only CentOS (possible Rhel) and is related with address space layout randomization http://searchsecurity.techtarget.com/definition/address-space-layout-randomization-ASLR We may get hhvm to work again by work around this problem in two ways:

1 - Disable ASR

Edit /etc/sysctl.conf and add:

kernel.randomize_va_space = 0

and then run:

sysctl -p

2 - Disable SELinux

Edit the file /etc/sysconfig/selinux and change SELINUX variable to disabled:

SELINUX=disabled

And then reboot the system.

Step 5 - Configure Nginx

Now lets check if hhvm and nginx properly work together. Copy the following content to the file /etc/nginx/sites-avaliable/default:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm;

        access_log /var/log/nginx/access.log;

        server_name _;
        location ~ \.(hh|php)$ {
           fastcgi_keep_conn on;
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
           include        fastcgi_params;
        }

        location / {
                try_files $uri $uri/ =404;
        }             
}

This will create a virtual host at nginx and set location to a fastcgi server located at 127.0.0.1 (localhost) using port 9000.

Now create a test.php file in /var/www/html:

 cd /var/www/html
 cat > test.php
 <php?
     if (defined('HHVM_VERSION')) {
       echo "HHVM OK";
     }

Now you need to restart nginx and hhvm:

 systemctl restart nginx
 systemctl restart hhvm

Now you can access test.php from our server by typing localhost/test.php at your browser or run:

curl localhost/test.php 

This should print OK on terminal.

###Set Magento Virtual Host

Magento offers a ready-made Nginx virtual host configuration, so we just have to include it in our configuration. Replace contents of /etc/nginx/sites-avaliable/default with:

upstream fastcgi_backend {
  server 127.0.0.1:9000;
}
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        access_log /var/log/nginx/access.log;

        server_name _;

        set $MAGE_ROOT /var/www/magento2;
        set $MAGE_MODE developer;

        include /var/www/magento2/nginx.conf.sample;

        location ~ /\.ht {
            deny all;
        }
}

And then restart nginx and hhvm again:

 systemctl restart nginx
 systemctl restart hhvm

Now Magento2 is installed and running on HHVM. You can access Magento by access localhost using a browser.