さくらのVPS 標準OSの環境構築(4) MariaDBとPHPのセットアップ

## 前回

[さくらのVPS 標準OSの環境構築(3) Webサーバーの設定](http://qiita.com/takahiko-takei/items/110a3da996e733e5a43c)


## MariaDBのインストールと設定

今回、データベースは`MariaDB`をインストールします。
`MariaDB`とは、`MySQL`のオリジナルコード作者であるMichael "Monty" Widenius氏が立ち上げたプロジェクトによって開発されているMySQLと互換性をもつオープンソースな関係データベース管理システム(RDBMS)です。


### リポジトリの追加とインストール

手動で`yum`リポジトリを追加します。

> `rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB && \`
> `vi /etc/yum.repos.d/mariadb.repo`

```diff:/etc/yum.repos.d/mariadb.repo
+ [mariadb]
+ name = MariaDB
+ baseurl = http://yum.mariadb.org/10.1.6/centos6-amd64
+ enabled=0
+ gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
+ gpgcheck=1
```

リポジトリが追加できたら、`yum`コマンドで`MariaDB`をインストールします。

> `yum install --enablerepo=mariadb MariaDB-devel MariaDB-client MariaDB-server`


### MariaDBの初期設定

`MariaDB`を一旦起動します。

> `service mysql start`

```shell-session:実行結果
Starting MySQL. SUCCESS!
```

`MariaDB`の初期設定を実行します。

> `mysql_secure_installation`

```shell-session:実行結果
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): <- 空Enter
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] <- 空Enter
New password: <- パスワードを入力
Re-enter new password: <- パスワードを再入力
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] <- 空Enter
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] <- 空Enter
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] <- 空Enter
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] <- 空Enter
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
```

`MariaDB`を一旦停止します。

> `service mysql stop`

```shell-session:実行結果
Shutting down MySQL... SUCCESS! 
```


### データベース設定とチューニング

中規模のベース設定ファイル`my-medium.cnf`を`my.cnf`にコピーします。

> `cp /usr/share/mysql/my-medium.cnf /etc/my.cnf.d/my.cnf`

カスタマイズ設定を追加します。
オリジナルの`server.cnf`をバックアップし、新規で`server.cnf`を作成します。

> `mv /etc/my.cnf.d/server.cnf /etc/my.cnf.d/server.cnf.orig && \`
> `vi /etc/my.cnf.d/server.cnf`

```diff:/etc/my.cnf.d/server.cnf
+ [mysqld]
+ datadir=/var/lib/mysql
+ character-set-server=utf8
+ symbolic-links=0
+ innodb_buffer_pool_size=64M
+ innodb_log_file_size=16M
+ innodb_flush_method=O_DIRECT
+ query_cache_size=128M
+ query_cache_limit=2M
+ query_cache_min_res_unit=4k
+ query_cache_type=1
+ tmp_table_size=128M
+ max_heap_table_size=128M
+ table_open_cache=1024
+ max_allowed_packet=1M
+ sort_buffer=256K
+ read_buffer_size=256K
+ read_rnd_buffer_size=256K
+ join_buffer_size=256K
+ key_buffer_size=16M
+ max_connections=256
+ thread_cache=256
+ wait_timeout=60
+ plugin-load = handlersocket.so
```

設定が終わったら`MariaDB`を起動します。

> `service mysql start`

`MariaDB`が起動したら、`MySQL Tuner`を使ってデータベースのチューニングをします。
`mysqltuner.pl`をダウンロードし、実行権限を与え実行します。
`ROOT_PASSWORD`は、初期設定で設定した`root`のパスワードを入力してください。

> `cd ~/ && \`
> `wget https://raw.github.com/rackerhacker/MySQLTuner-perl/master/mysqltuner.pl && \`
> `chmod +x mysqltuner.pl && \`
> `./mysqltuner.pl -user root -pass ROOT_PASSWORD`


## PHPのビルドと設定

`PHP`は、バージョンをすぐ切り替えられるようにしたいので、`phpenv`で管理するようにします。
また`phpenv`を使うにあたって、他の`\*env`系とバッティングしないよう`anyenv`を通してインストールします。


### anyenvのインストール

[GitHub](https://github.com/riywo/anyenv)からクローンしてきます。

> `git clone https://github.com/riywo/anyenv ~/.anyenv`

```shell-session:実行結果
Initialized empty Git repository in /root/.anyenv/.git/
remote: Counting objects: 172, done.
remote: Total 172 (delta 0), reused 0 (delta 0), pack-reused 172
Receiving objects: 100% (172/172), 26.63 KiB, done.
Resolving deltas: 100% (57/57), done.
```

`anyenv`のPATHを通します。

> `vi ~/.bashrc`

```diff:~/.bashrc
+ # anyenv
+ if [ -d ~/.anyenv ]; then
+     export PATH=$PATH:$HOME/.anyenv/bin
+     eval "$(anyenv init -)"
+ fi
```

設定を保存したら、設定ファイルを`source`コマンドで一度実行します。

> `source ~/.bashrc`


### phpenvのインストール

`anyenv`のPATHが通ったら、`anyenv`から`phpenv`をインストールします。
`anyenv`から`phpenv`をインストールすると、`PHP`のビルド用プラグイン`php-build`が自動的にインストールされます。

> `anyenv install phpenv`

```shell-session:実行結果
/tmp/phpenv.20150831090000.1979 ~
Cloning https://github.com/laprasdrum/phpenv.git...
Initialized empty Git repository in /tmp/phpenv.20150831090000.1979/phpenv/.git/
remote: Counting objects: 92, done.
remote: Compressing objects: 100% (61/61), done.
remote: Total 92 (delta 27), reused 92 (delta 27), pack-reused 0
Unpacking objects: 100% (92/92), done.
~
~/.anyenv/envs/phpenv/plugins ~
Cloning https://github.com/CHH/php-build.git...
Initialized empty Git repository in /root/.anyenv/envs/phpenv/plugins/php-build/.git/
remote: Counting objects: 3417, done.
remote: Total 3417 (delta 0), reused 0 (delta 0), pack-reused 3417
Receiving objects: 100% (3417/3417), 500.39 KiB | 267 KiB/s, done.
Resolving deltas: 100% (2012/2012), done.
~

Install phpenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```

`phpenv`インストール完了後、メッセージ通り下記のコマンドを実行します。

> `exec $SHELL -l`

`phpenv`が正常にインストールされたか確認します。
`phpenv: command not found`と表示されていなければ大丈夫です。

> `anyenv version`

```shell-session:実行結果
phpenv: system (set by /root/.anyenv/envs/phpenv/version)
```


### PHPのビルド依存パッケージのインストール

`PHP`のビルドに必要な依存パッケージをまとめてインストールします。

> `yum --enablerepo=epel install re2c libmcrypt libmcrypt-devel && \`
> `yum install libxml2-devel bison bison-devel openssl-devel curl-devel libjpeg-devel libpng-devel libmcrypt-devel readline-devel libtidy-devel libxslt-devel enchant-devel libXpm libXpm-devel freetype-devel t1lib t1lib-devel gmp-devel libc-client-devel libicu-devel oniguruma-devel net-snmp net-snmp-devel bzip2-devel`


### ImageMagickのインストール

2016年5月3日頃公開されたImageMagickの脆弱性(CVE-2016-3714他)の対応として、最新版のImageMagickをインストールします。

> `rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm`
> `yum install --enablerepo=remi,epel ImageMagick-last ImageMagick-last-devel ImageMagick-last-libs`


### ビルドオプションの変更

ビルドオプションを`default_configure_options`に追記します。

`PECL`を使えるようにするため、`--without-pear`を`--with-pear`に変更します。
また、各オプションを使えるようにするために色々追記します。

> `vi ~/.anyenv/envs/phpenv/plugins/php-build/share/php-build/default_configure_options`

```diff:~/.anyenv/envs/phpenv/plugins/php-build/share/php-build/default_configure_options
- --without-pear
+ --with-pear
:
+ --with-apxs2=/usr/bin/apxs
+ --enable-fileinfo
+ --enable-hash
+ --enable-json
+ --enable-sysvmsg
+ --with-bz2
+ --enable-ctype
+ --with-iconv
+ --enable-ftp
+ --with-gettext
+ --enable-mbstring
+ --with-onig=/usr
+ --with-pcre-regex
+ --with-mysql-sock=/var/lib/mysql/mysql.sock
+ --enable-phar
+ --enable-shmop
+ --enable-sockets
+ --enable-simplexml
+ --enable-dom
+ --with-libxml-dir=/usr
+ --enable-tokenizer
+ --with-kerberos=/usr
+ --with-openssl=/usr
+ --enable-zip
+ --with-mhash=yes
+ --without-mm
+ --with-enchant=/usr
+ --enable-gd-native-ttf
+ --with-gmp=/usr
+ --with-xpm-dir=/usr/X11R6
+ --with-freetype-dir=/usr
+ --with-imap=/usr
+ --with-imap-ssl
+ --enable-intl
+ --with-t1lib=/usr
+ --with-snmp=/usr
```

ビルドオプションは`phpenv install`時に`CONFIGURE_OPTS`でその場限りの追加指定をすることもできます。

> **実行例**
> `CONFIGURE_OPTS="--with-pear --disable-fpm --with-apxs2=/usr/bin/apxs" phpenv install 5.x.x`


### ビルド可能なPHPのバージョン一覧の確認

現在の`php-build`でビルド可能な`PHP`のバージョンの一覧を出力します。

> `phpenv install -l`

```shell-session:実行結果
Available versions:
  5.2.17
  5.3.2
  5.3.3
  : (省略)
  7.0.5
  7.0snapshot
  master
```


### ビルド可能なPHPのバージョン一覧を更新

`php-build`のビルド可能な`PHP`のバージョン一覧を更新します。

> `cd ~/.anyenv/envs/phpenv/plugins/php-build/ && \`
> `git pull`


### PHPのビルド

`PHP`のビルドを実行します。
今回は執筆当時の`5.6`の最新版`5.6.20`をインストールします。

> `phpenv install 5.6.20`

```shell-session:実行結果
[Info]: Loaded extension plugin
[Info]: Loaded apc Plugin.
 : (省略)
[Success]: Built 5.6.20 successfully.
```

ビルドの完了後、生成された`libphp5.so`は**必ず**ビルドされたバージョンのディレクトリに移動させます。

> `mv /opt/rh/httpd24/root/usr/lib64/httpd/modules/libphp5.so ~/.anyenv/envs/phpenv/versions/5.6.20/libexec/libphp5.so`
> > 移動させないと、ビルドのたびに`libphp5.so`が上書きされてしまうため、上書き回避のために必ず退避します。
> > こうすることで`httpd.conf`でのバージョン切り替えも容易になります。


### CLI側のPHPの切り替え

PHPのビルド成功後、CLIが読み込むPHPのバージョンを切り替えます。

> phpenv global 5.6.20
 
バージョンの切り替えが成功しているか確認します。
切り替えたバージョンが表示されていれば成功です。

> `anyenv version && \`
> `php -v`

```shell-session:実行結果
phpenv: 5.6.20 (set by /root/.anyenv/envs/phpenv/version)
PHP 5.6.20 (cli) (built: Sep  1 2015 09:00:00) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans
```


### Apache側のPHPの切り替え

あわせて、`Apache`が読み込む`PHP`のバージョンを切り替えます。
こちらはCLIとは別で指定する必要がある上に、CLIのように切り替えコマンドもないので注意してください。

> `vi /etc/httpd/conf/httpd.conf`

`httpd.conf`の下記のコメント行の次の行辺りに、ビルドするたびに自動で`LoadModule php5_module`の記述が追記されていきます。
`LoadModule php5_module`が複数行あると`Apache`再起動時にエラーになります。
2回目以降のバージョンの追加・切り替えを行う際は、`LoadModule php5_module`は1行だけ残すことを覚えておきましょう。

```diff:/opt/rh/httpd24/root/etc/httpd/conf/httpd.conf
  :
  # Example:
  # LoadModule foo_module modules/mod_foo.so
- LoadModule php5_module /root/.anyenv/envs/phpenv/versions/5.6.19/libexec/libphp5.so
+ LoadModule php5_module /root/.anyenv/envs/phpenv/versions/5.6.20/libexec/libphp5.so
  :
```


### PECLでImageMagickをインストール

詳細な画像処理を行う`ImageMagick`パッケージをインストールします。

> `pecl install imagick`
> > `PECL`からインストールする`extension`は、現在指定しているバージョンにしか入らないため、バージョンの追加・切り替え毎に`pecl install`でインストールする必要があります。


### PHPの設定

`ImageMagick`のインストールが完了したら設定ファイル`php.ini`を編集します。

> `vi ~/.anyenv/envs/phpenv/versions/5.6.20/etc/php.ini`

```diff:~/.anyenv/envs/phpenv/versions/5.6.20/etc/php.ini
  :
+ extension=imagick.so
  :
- ;date.timezone = 
+ date.timezone = Asia/Tokyo
  :
- post_max_size = 8M
+ post_max_size = 100M
  :
- upload_max_filesize = 2M
+ upload_max_filesize = 100M
  :
- ;mbstring.language = Japanese 
+ mbstring.language = Japanese
  :
- ;mbstring.internal_encoding = 
+ mbstring.internal_encoding = UTF-8
  :
- ;mbstring.detect_order = auto
+ mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
  :
- pdo_mysql.default_socket=
+ pdo_mysql.default_socket=/var/lib/mysql/mysql.sock
  :
- mysql.default_socket =
+ mysql.default_socket = /var/lib/mysql/mysql.sock
  :
- mysqli.default_socket =
+ mysqli.default_socket = /var/lib/mysql/mysql.sock
  :
```


### PECLでAPCuをインストール

高速化のために、ユーザーデータをメモリ内にKVS(Key Value Store)形式でキャッシュする**データキャッシュ機能**をもつ`APCu`をインストールします。

> `pecl install apcu`

設定ファイルを作成し、`PHP`ビルド時に組み込まれているPHPアクセラレータ`OPCache`の設定も同時に設定を行います。
`opcache.blacklist_filename`のパスはビルドしたバージョンの`/etc/conf.d/`内を指定します。(多分)

> `vim ~/.anyenv/envs/phpenv/versions/5.6.21/etc/conf.d/apc.ini`

```diff:~/.anyenv/envs/phpenv/versions/5.6.21/etc/conf.d/apc.ini
+ [opcache]
+ opcache.enable = 1
+ opcache.enable_cli = 1
+ opcache.memory_consumption = 128
+ opcache.interned_strings_buffer = 8
+ opcache.max_accelerated_files = 4000
+ opcache.blacklist_filename = /root/.anyenv/envs/phpenv/versions/5.6.21/etc/conf.d/opcache*.blacklist
+ [apcu]
+ extension = apcu.so
+ apc.enabled = 1
+ apc.enable_cli = 1
+ apc.shm_size = 64M
+ apc.mmap_file_mask = /tmp/apc.XXXXXX
```


### Apacheの再起動

PHPのバージョンの追加・切り替え・`extension`の追加などが終わったら、Apacheを再起動させます。

> `service httpd24-httpd restart`


## 次回

[さくらのVPS 標準OSの環境構築(5) Let's EncryptでSSL+HTTP/2対応](http://qiita.com/takahiko-takei/items/ce34defe0273a22e8baa)