CentOS7 環境設定 (Apache2.4 EventMPM + php-fpm + php7.4)

# はじめに
今回は、CentOS7にApache2.4（EventMPM）とPHP7.4と、php-fpmをYumを使って、インストールします。
使っているのは、さくらVPSです。（散々解説された内容の記事ですが、メモのために書いています。）

# リポジトリの準備
PHPの最新版をYumでインストールするために、EPELとremiリポジトリを追加します。

## epel リポジトリの追加

さくらVPSを利用している場合は、基本的にEPELリポジトリは追加された状態で提供されているので、次項のremiリポジトリの追加にスキップしてもOKです。

```sh
yum -y install epel-release
```

## remi リポジトリの追加
```sh
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

# Apacheのインストール＋設定

## Apacheのインストール

```sh
yum -y install httpd httpd-devel
```

## ApacheをEventMPMで動かす設定

```sh
vi /etc/httpd/conf.modules.d/00-mpm.conf
```

デフォルトでは、preforkで動く設定になっているので、その設定をコメントアウトで無効にし、代わりにeventで動く設定のコメントアウトを外してを有効にします。

```conf:/etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so  # <<< 先頭に#を付けてコメントアウト

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so # <<< 先頭の#を取って有効にする。
```
## Apacheを起動してみる
ここまで済んだら、Apacheを起動してみます。

```sh
systemctl start httpd.service
```
何も表示されず不安なので･･･ちゃんと動いているか確認してみます。

```sh
systemctl status httpd.service
```
ゴチャゴチャ表示されますが、`Active: active (running)`と表示があればOKです。

## Apacheを自動起動に設定する
サーバーを再起動した時に、自動で起動するように設定しておきます。

```sh
systemctl enable httpd.service
```

```sh
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
```
とかなんとか表示されます。シンボルリンクを作ったというログですね。

# PHPをインストール
一般的に使用頻度が高いモジュールは一緒にインストールしておきます。
また、`--enablerepo=remi-php74`のオプションを付けるのがポイントです。`yum install php74`でもインストール自体はできますが、php-mbstirngなどのモジュールをインストールするが非常に煩わしいので、リポジトリを指定しておきます。（標準のPHPにインストールされます）

```sh
yum --enablerepo=remi-php74 -y install php php-devel php-mbstring php-gd php-pdo php-pgsql php-mysqlnd php-mcrypt php-xml php-bcmath php-tokenizer php-zip php-pecl-xdebug php-opcache php-pecl-apcu
```

上記のコードは、私が必要な物を入れています。使わない物は入れなくて大丈夫です。また、Laravelを見据えた構成にしてあります。大は小を兼ねるということで入れておくのもよいでしょう。

*yum updateを実行した時に、PHP関連でエラーが出る時は、remi-php74を許可してアップデートをしましょう。*

```sh
yum --enablerepo=remi-php74 update
```

## Apacheの設定に立ち返る

PHPをインストールすると、自動でApacheの設定内に、モジュール動作での設定が書き込まれるのでコメントアウトします。

```conf:/etc/httpd/conf.modules.d/15-php.conf
#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#

#-- 以下、php-fpm利用に際しコメントアウト
# Cannot load both php5 and php7 modules
#<IfModule !mod_php5.c>
#  <IfModule prefork.c>
#    LoadModule php7_module modules/libphp7.so
#  </IfModule>
#</IfModule>


#<IfModule !mod_php5.c>
#  <IfModule !prefork.c>
#    LoadModule php7_module modules/libphp7-zts.so
#  </IfModule>
#</IfModule>
```

## PHPの忘れがちな設定

PHPのバージョン等がヘッダーに出力されなくする設定と、日付関連を日本時間（UTC+9)にする設定をここでやっておきたいと思います。

```ini:/etc/php.ini

(略）

; Decides whether PHP may expose the fact that it is installed on the server
; (e.g. by adding its signature to the Web server header).  It is no security
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
; http://php.net/expose-php
expose_php = Off

(略)

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Asia/Tokyo"

```

# PHP-FPMをインストールする。

前項のPHPのインストールで一緒にインストールしても良かったんですが、重要なので敢えて分けでインストールしています。

```sh
yum --enablerepo=remi-php74 -y install php-fpm
```

起動＋自動起動の設定をします。

```sh
systemctl start php-fpm
```

```sh
systemctl enable php-fpm
```

# ApacheとPHP-FPMを関連付ける

このままでは、PHPを実行できません。Apacheにアクセスがあって、拡張子がphpの場合には、PHP-FPMにで処理をするように変更します。先に変更した設定ファイルを再度変更します。

```sh
vi /etc/httpd/conf.modules.d/00-mpm.conf
```

```conf:/etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so  # <<< 先頭に#を付けてコメントアウト

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so # <<< 先頭の#を取って有効にする。

# ここから追記
<IfModule mpm_event_module>
        StartServers            3
        MinSpareThreads         24
        MaxSpareThreads         48
        ThreadsPerChild         64
        MaxRequestWorkers       128
        MaxConnectionsPerChild  0
       <FilesMatch \.php$>
                SetHandler "proxy:fcgi://127.0.0.1:9000"
       </FilesMatch>
</IfModule>
```

設定を変更したら、Apacheを再起動

```sh
systemctl restart httpd
```

以上で、基本的な設定は終了です。enjoy!

# 番外編）phpがUTF-8を扱えるようにする。
basename関数などで、日本語のファイル名の取得など一部の関数で日本語がうまく扱えない！などという状況を回避するために最低限度の設定をしておきます。以下に書くのは、**日本語(UTF-8)**にするための設定です。

まず、OSのロケールを確認する。

```sh
locale
```

日本語になっていなければ、日本語（UTF-8)に変更します。

```sh
localectl set-locale LANG=ja_JP.UTF-8
```

設定を反映させる

```sh
source /etc/locale.conf
```

OSのlocaleを変更するのが、運用上問題な場合は、PHPだけで処理する方法もあります。

```php
<?php
// ロケールの設定
setlocale(LC_ALL, 'ja_JP.UTF-8');
?>
```

mbstringの使用は、どんどん非推奨になっていっていますが、取りあえず設定しておく。

```ini:/etc/php.ini
:
[mbstring]
mbstring.language = Japanese
:
mbstring.internal_encoding = UTF-8
:
mbstring.http_output = UTF-8
:
```


# 番外編）拡張子がhtmlでも、PHPを動かしたい

上記の設定だと、PHPが実行されるのは、.phpの拡張子のみです。
拡張子が.htmlではphpを実行することができません。実行できるようにするには以下の設定が必要です。


**PHP-FPMで拡張子を認識させる設定**

```sh
vi /etc/php-fpm.d/www.conf
```

```conf:/etc/php-fpm.d/www.conf
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; execute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5 .php7
;以下を追記
security.limit_extensions = .php .html 
```

**Apacheで拡張子を認識させる設定**

```sh
vi /etc/httpd/conf.modules.d/00-mpm.conf
```

```conf:/etc/httpd/conf.modules.d/00-mpm.conf
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so

<IfModule mpm_event_module>
        StartServers            3
        MinSpareThreads         24
        MaxSpareThreads         48
        ThreadsPerChild         64
        MaxRequestWorkers       128
        MaxConnectionsPerChild  0
       <FilesMatch \.(php|html)$>
                SetHandler "proxy:fcgi://127.0.0.1:9000"
       </FilesMatch>
</IfModule>
```

設定を保存したら、php-fpmと、httpd(Apache）を再起動する。

```sh
systemctl restart php-fpm
systemctl restart httpd
```


# 番外編）間違えてyumでインストールしたものを削除したい

インストール時はアンインストールも考えろと爺さんが言っていたので･･･
取り敢えず、メモしておく。

```sh
yum remove php
```

# 番外編） 設定を変更した時は･･･
`/etc/php.ini`を変更したら、php-fpmを再起動する。
PHPをApacheのモジュールモードで動かしている時は、Apacheを再起動させますが、これはCGIモードですから、php-fpmを再起動させる必要があります。念のため、Apacheも再起動させましょう。

```sh
systemctl restart php-fpm
systemctl restart httpd
```

`/etc/httpd/conf/httpd.conf` や、 `/etc/httpd/conf.modules.d/*.conf` などのApacheの設定を変更した場合は、今まで通り、httpdだけ再起動で問題ありません。

```sh
systemctl restart httpd
```

## 続き：CentOS7 環境設定 （Apache2.4 + Let's Encrypt）
Let's Encryptを使ったHTTPS化の備忘録も追加。
https://qiita.com/daichi_pd/items/14cb3eb03ad796b01ea5