facts

オワタ\(^o^)/


CentOS 7.1 (1503)にHHVM 3.9をインストールしてApache 2.4でsuEXECのように動かす

2015/08/27 0:04] 投稿者: lazycat カテゴリー: WordPress, さくらのVPS

HHVMなるものを今更知ったのですが、速いとのことで、おもしろそうなので入れてみることにします。
タイミングのいいことに、HHVM3.9がリリースされたばかりです。
WordPressは動作するっぽいです。
このところCentOS 7漬けです。

Ubuntuはapt-getでインストールできるようですが、残念ながらCentOS 7パッケージの提供はありません。

“CentOS 7 HHVM”でググっても、謎のレポジトリのパッケージからインストールしていたり、そもそもCentOS 6用のパッケージをインストールしていたりする内容が出てくるのですが、後々トラブルが出そうでちょっと同じようには行いたくない感じです。

パッケージがない以上ビルドするしかないわけですが、日本語でまとめてあるのは下記のサイトぐらいでした。
http://y-uti.hatenablog.jp/entry/2014/07/11/060126
2014年の記事というかCentOS 7が出たばかりの頃の記事なので、ビルドまでの道のりが少しと思ってもう少し調べたら本家に書いてありました…。
CentOS 7が出てから1年も経ってますからね。

https://github.com/facebook/hhvm/wiki/Building-and-installing-hhvm-on-CentOS-7.x

この手順をベースに進めますが、実際に試すと書いてあることだけではうまくいきませんでした。
断片的な情報を集めて試行錯誤しましたが、最終的にはうまくいきました。

今回もsuEXECもどきです。Apacheと組み合わせてHHVMをユーザー権限で動作させます。

まずは、ビルドに必要なパッケージをインストールします。
EPELが必要です。

今更ですが、EPELは”yum install epel-release”で、インストールできます。

# yum install cpp gcc-c++ cmake git psmisc {binutils,boost,jemalloc}-devel \
{ImageMagick,sqlite,tbb,bzip2,openldap,readline,elfutils-libelf,gmp,lz4,pcre}-devel \
lib{xslt,event,yaml,vpx,png,zip,icu,mcrypt,memcached,cap,dwarf}-devel \
{unixODBC,expat,mariadb}-devel lib{edit,curl,xml2,xslt}-devel \
glog-devel oniguruma-devel ocaml gperf enca libjpeg-turbo-devel openssl-devel \
make --enablerepo=epel

実際にEPELからインストールされるのは、
enca
glog-devel
jemalloc-devel
libmcrypt-devel
lz4-devel
oniguruma-devel
だけでした。

“–enablerepo=epel”を付け忘れたら、
# yum install jemalloc-devel lz4-devel libmcrypt-devel glog-devel oniguruma-devel enca –enablerepo=epel
します。別に書かなくてもいいですね。

ccacheがインストールされていると自動で使ってくれるようなので、ccacheもインストールします。
ビルドし直すときに効果を発揮します。できればmakeは一度で終わりたいです。
# yum install ccache –enablerepo=epel

ソース用のディレクトリを作成します。
# mkdir ~/dev
# cd ~/dev

gitからソースコードを入手します。最新はこれです。
# git clone https://github.com/facebook/hhvm -b master hhvm –recursive

今回はHHVM-3.9.1を指定してみました。(※2015/10/14 HHVM 3.9.1に変更しました。)
# git clone https://github.com/facebook/hhvm -b HHVM-3.9.1 hhvm –recursive
かなり大きいので時間がかかります。

hhvmディレクトリに移動します。
# cd hhvm

※追記
そのままビルドすると、UNIX domain socketで動作させた場合に、socketのアクセス権が760なってしまいユーザー権限で動かす際に不都合があるのでソースを一カ所修正します。
# vi hphp/runtime/server/fastcgi/fastcgi-server.cpp

if (m_socketConfig.bindAddress.getFamily() == AF_UNIX) {
auto path = m_socketConfig.bindAddress.getPath();
chmod(path.c_str(), 0760);
}
↓113行目あたりにある0760を0766に変更します。
if (m_socketConfig.bindAddress.getFamily() == AF_UNIX) {
auto path = m_socketConfig.bindAddress.getPath();
chmod(path.c_str(), 0766);
}

この部分の変更でリビルドしましたが、2分くらいで終わりました。
入れててよかったccache。
※追記ここまで

自分でビルドしたものは標準のディレクトリに入れるとトラブル時に面倒なので、cmake実行時にprefixを指定します。
/opt/hhvmにインストールします。
こうすれば、問題が出たり要らなくなったときにさくっと消すことができます。
“-march=native”も指定してみました。

cmake \
    -DCMAKE_INSTALL_PREFIX:PATH=/opt/hhvm \
    -DCMAKE_C_FLAGS="-march=native" \
    -DCMAKE_CXX_FLAGS="-march=native" \
    .

「make with CORE_COUNT+1 threads, that would be fast. You may run out of RAM」ということで、
# make -j$(($(nproc)+1))
でmakeします。
さくらのVPS 1Gだとメモリも少ないですし、ただのmakeでもいいと思います。

環境次第ですが1~2時間くらいかかります。

Embedding php in hhvm
Creating symlinks for hhvm
[100%] Built target hhvm

と表示されたら完了です。

テストします。
# ./hphp/hhvm/hhvm –version

HipHop VM 3.9.1 (rel)
Compiler: tags/HHVM-3.9.1-0-g0f72cfc2f0a01fdfeb72fbcfeb247b72998a66db
Repo schema: 41db3511d4f69e5584304f64434cb13aa602e1ee

上記のようにバージョンが表示されます。(※2015/10/14 HHVM 3.9.1に変更しました。)

インストールします。
# make install

ビルドディレクトリを抜けます。
# cd ~

HHVMのサービスを追加します。
# vi /etc/systemd/system/hhvm.service

[Unit]
Description=HHVM HipHop Virtual Machine (FCGI)
After=syslog.target network.target

[Service]
ExecStartPre=-/usr/bin/mkdir -p /var/run/hhvm
ExecStartPre=-/usr/bin/chmod 777 /var/run/hhvm
ExecStart=/opt/hhvm/bin/hhvm --config /etc/hhvm/server.ini --mode daemon

ExecStartPost=-/usr/bin/sleep 2s
ExecStartPost=-/usr/bin/chmod 766 /var/run/hhvm/hhvm.sock

Restart=on-failure

[Install]
WantedBy=multi-user.target
DirectoryIndex

socketが標準だと760のアクセス権で作成されます。
PHP-FPMの時は666なので問題なかったのですが、760だとHHVMをユーザー権限で動かすことができません。
ExecStartPostでHHVMの起動後にアクセス権を変更しています。
すぐにchmodを行うとファイルがないと言われるので、sleepを入れています。
※追記:ExecStartPostでchmodを行う方法は、負荷が高いときや起動時にsleep 2sを入れても安定しない場合があったのでので、ソースを書き換えることにしました。

ExecStartであまりオプションを指定していませんが、ここでは最低限のオプションを指定し、設定はserver.iniファイルに代わりに書きます。

設定ファイル用のディレクトリを作成します。
# mkdir /etc/hhvm

設定ファイルを作成します。
# vi /etc/hhvm/server.ini

hhvm.server.user = apache

hhvm.server.type = fastcgi
hhvm.server.file_socket = /var/run/hhvm/hhvm.sock
hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc
pid = /var/run/hhvm/pid

hhvm.log.header = true
hhvm.log.use_log_file = true
hhvm.log.file = /var/log/hhvm/error.log

hhvm.server.fix_path_info = true

date.timezone = "Asia/Tokyo"
session.cookie_httponly = 1
session.hash_function = 1

session.save_handler=memcache
session.save_path="tcp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

server.iniはhhvmの設定と、php.iniが合体したような感じです。
memcachedも使用するようにしました。設定値はmemcacheです。

試行錯誤した結果、”hhvm.server.fix_path_info = true“を指定するのがポイントでした。
これがあると、Apache側では

<FilesMatch "\.php$">
    SetHandler "proxy:unix:/var/run/hhvm/hhvm.sock|fcgi://localhost/"
</FilesMatch>

でphpをHHVMで動かすことができます。
このオプションがないとphpを動かすとパスが変になって、PHP-FPMのようにFilesMatchとSetHandlerでfcgi proxyを使うことができません。
“hhvm.server.fix_path_info = true”なしの場合はProxyPassMatchで動かすことになりますが、ProxyPassMatchはDirectoryIndexが効かなかったりするのでおすすめできません。

ログのディレクトリとファイルを作成します。
# mkdir /var/log/hhvm
# touch /var/log/hhvm/error.log
# chown apache:apache /var/log/hhvm/error.log

サービスを起動します。
# systemctl start hhvm
# systemctl enable hhvm

例としてapache権限で動かす設定を記載しましたが、apache以外のユーザーで動かすことも可能なので、suEXECもどきとしても使えます。

例えば、
サービスと設定ファイルを
/etc/systemd/system/hhvm-user.service
/etc/hhvm/server-user.ini
みたいにして、

server-user.iniで

hhvm.server.user = user

hhvm.server.file_socket = /var/run/hhvm/hhvm-user.sock
hhvm.repo.central.path = /var/run/hhvm/hhvm-user.hhbc
pid = /var/run/hhvm/pid-user

hhvm.log.file = /var/log/hhvm/user.log

という感じにして、

ApacheではVirturalHostなどで、

<FilesMatch "\.php$">
    SetHandler "proxy:unix:/var/run/hhvm/hhvm-user.sock|fcgi://localhost/"
</FilesMatch>

とすれば、HHVMの実行ユーザーを変えることができます。

PHP-FPMで設定したときはPHP-FPMのサービスは一つでしたが、だいたい同じですね。

CentOS 7.1 (1503)でApache 2.4 Event MPM(suEXEC)とsuEXECもどきのPHP-FPMとMemcachedを組み合わせて動かす

2015/08/12 14:19] 投稿者: lazycat カテゴリー: WordPress, さくらのVPS

さくらのVPSにCentOS 7をセットアップした時の備忘録です。
Apache 2.4 Event MPMとPHP-FPMを組み合わせて使います。
CGIはsuEXECで動きます。PHPはsuEXECみたいに動きます。
PHPのセッション管理はmemcachedを使用します。

PHP-FPMだとnginxの情報が多くて、同じ構成はググっても出てきませんでした。
いろんな情報を参考にまとめました。
ユーザー名は”user”として書いてあります。

以前はremiやrpmforgeレポジトリを使用していましたが、サポート期間の不安や、パッケージの依存関係で問題が出るとどうにもならなくなるので、基本的に標準レポジトリしか使いません。
どうしてもパッケージがない場合にEPELのみ使用します。

yumでhttpd php-cli php-fpm memcached php-pecl-memcacheあたりをインストールします。
モジュール版のphpは不要です。

PHPのsuEXECもどきの設定をします。
併せてMemcachedを使用する設定をします。

# vi /etc/php.d/memcache.ini
下の方にあるsession.save_handlerとsession.save_pathのコメントを取ります。

; Use memcache as a session handler
session.save_handler=memcache
; Defines a comma separated of server urls to use for session storage
session.save_path="tcp://localhost:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

# vi /etc/php.ini
コメントアウトします。

;session.save_handler = files

PHP-FPMの設定をします。
ユーザーごとに設定ファイルを作成します。
ログも分けます。
PHP-FPMはunix socketで動かします。
標準の/etc/php-fpm.d/www.confが不要であれば削除するかリネームします。

# vi /etc/php-fpm.d/user.conf

[user]
listen = /var/run/php-fpm/php-fpm-user.sock
user = user
group = user

pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4

php_admin_value[error_log] = /var/log/php-fpm/user.log
php_admin_flag[log_errors] = on

ログファイルを作成します。
# touch /var/log/php-fpm/user.log
# chown user:user /var/log/php-fpm/user.log

/var/log/php-fpmのアクセス権が770なのでそのままだとログが書き込みできません。
書き込みできるようにログディレクトリのアクセス権を変更します。
# chmod 775 /var/log/php-fpm

PHP-FPMのunix socketをバーチャルホストごとに変更すれば、PHPの実行ユーザーを変えられます。

次に、CGIのsuEXECです。

CentOS 7のsuEXECは/var/www/…./public_htmlというディレクトリでないと動作しないので、suEXECが動作する環境を作ります。
/var/wwwの下にユーザーディレクトリを持ってくるのは微妙です。
SSHのchrootも有効にしているので、ユーザーディレクトリからのシンボリックも使えません。
/var/wwwの下からシンボリックリンクを作成しても、今度はsuEXECがシンボリックリンクで動作しません。
シンボリックリンクではなく、mountのbindオプションを使用します。

/home/userの下に、public_htmlを作成し、バーチャルホストの公開ディレクトリにします。

# mkdir /home/user/public_html
# chown user:user /home/user/public_html
# chmod 701 /home/user/public_html(Apacheの動作にXX1が必要です)

mount –bindでマウントします。
# mkdir /var/www/home
# mount –bind /home /var/www/home
これで、/var/www/homeが/homeと同じ内容になります。

起動時からマウントするように、/etc/fstabに追加します
# echo “/home /var/www/home none bind 0 0” >> /etc/fstab

これで、Apache以外の準備はできました。

Apacheの設定です。

# vi /etc/httpd/conf.modules.d/00-mpm.conf
Event MPMに変更。

#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_event_module modules/mod_mpm_event.so

# vi /etc/httpd/conf.modules.d/00-proxy.conf
proxy_fcgi_moduleはPHP-FPMで使用する。

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

バーチャルホストごとに、CGIとPHPの実行ユーザーを実際のユーザーにします。
# vi /etc/httpd/conf/httpd.conf

<VirtualHost *:80>
    SuexecUserGroup user user
    DocumentRoot "/var/www/home/user/public_html"
    ServerName virtual.example.com
    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/var/run/php-fpm/php-fpm-user.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

<Directory "/var/www/home/user/public_html">
    Options ExecCGI
    AllowOverride None
    Require all granted
</Directory>

CGIはSuexecUserGroupでユーザーを指定します。
PHPはfcgi proxyを使用して、ユーザーごとに作成したPHP-FPMのunix socketを使用します。

これでおしまいです。

WordPressのピンバックが文字化け

2012/12/13 16:59] 投稿者: lazycat カテゴリー: WordPress

さっきすごく久々に投稿して、WP Multibyte Patchが有効だと、ピンバックが文字化けするのを思い出した。
1年くらい前に確認したんだけど、今のバージョンでも同じでした。

昨日WordPress 3.5 日本語版リリースだったのか。

WordPress 3.1

2011/03/01 22:30] 投稿者: lazycat カテゴリー: WordPress

何が変わったのかは知らないが、とりあえずアップデート。

いつも通りの作業。

/wp-includes/js/tinymce/themes/advanced/skins/wp_theme/content.css
body.mceContentBody
font: 13px/19px “Lucida Grande”, “Hiragino Kaku Gothic ProN”, sans-serif;
に変更

/wp-includes/link-template.php
function get_next_posts_link
return ‘<a href=”‘

return ‘<a rel=”next” href=”‘