Apache + php (cgi) の環境構築

# 背景
Apache + php で環境構築したことはあるのですが、php はモジュール版でしか環境構築したことがなかったため、手順として残します。

FPM で動かす前に普通の cgi で動かしてみたかったので、この記事は cgi を使用しております。
cgi 版とモジュール版だとモジュール版のほうが動作は早いので実用性は低いです。

Webサーバで cgi 版を使うなら、php-fpm を使いましょう。

仕事ではソースコードからインストールするのですが、今回はWebサーバとして公開しないのと設定ファイルの確認程度なので、`yum` でインストールします。

インストール後にきれいに後片付けできるように docker のコンテナ上で作業します。

# 環境
ホストOS：Amazon Linux release 2 (Karoo)
コンテナOS：CentOS Linux release 7.9.2009 (Core)
Docker version 20.10.4
Apache/2.4.6
PHP 5.4.16 (cli)


# 手順
## コンテナの用意
コンテナを作成、起動します。

```
sudo docker run -tid -v /opt/app/:/var/www/html -p 80:80 centos:centos7
```

コンテナに入ります。
86 はコンテナIDです。

```
sudo docker exec -ti 86 bash
```

## Apache のインストール
まずは `yum update` します。

```
yum update -y
```

その後、Apache をインストールします。

```
yum install -y httpd
```

Apache を起動して、testページが表示されるか確認します。

```
httpd -k start
```

testページが表示されたらOKです。

## php のインストール
次にphpをインストールします。

```
yum install -y php
```

php の動作確認のため、ドキュメントルートにファイルを配置します。

```
vi /var/www/html/index.php
<?php echo phpinfo(); ?>
```

apache を再起動します。

```
httpd -k stop
httpd -k start
```

ブラウザで phpinfo が表示されたらOKです。

phpinfo を確認すると現在、php がモジュール版かCGI版どちらで動いているか確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184532/1694bcd1-034d-4810-8f4f-bbca504c01cf.png)

現状、モジュール版で動いているのでCGI版に変更していきます。

## CGI版への切り替え
### モジュール版PHPの読み込みをやめる
まずはモジュール版PHPの読み込みをしないようにします。
以下のようにコメントアウトします。

```:/etc/httpd/conf.modules.d/10-php.conf

#<IfModule prefork.c>
#  LoadModule php5_module modules/libphp5.so
#</IfModule>

```

### php.conf の編集
php.conf はデフォルトだと以下のようになってます。

```:/etc/httpd/conf.d/php.conf
#
# Cause the PHP interpreter to handle files with a .php extension.
#
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

#
# Allow php to handle Multiviews
#
AddType text/html .php

#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php

#
# Uncomment the following lines to allow PHP to pretty-print .phps
# files as PHP source code:
#
#<FilesMatch \.phps$>
#    SetHandler application/x-httpd-php-source
#</FilesMatch>

#
# Apache specific PHP configuration options
# those can be override in each configured vhost
#
php_value session.save_handler "files"
php_value session.save_path    "/var/lib/php/session"
```

これを以下のように編集しました。

```:/etc/httpd/conf.d/php.conf
#
# Cause the PHP interpreter to handle files with a .php extension.
#
<FilesMatch \.(php|phps)$>
    SetHandler php54-cgi
</FilesMatch>

#
# Allow php to handle Multiviews
#
#AddType text/html .php

Action php54-cgi /cgi-bin/php54

#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php

#
# Uncomment the following lines to allow PHP to pretty-print .phps
# files as PHP source code:
#
#<FilesMatch \.phps$>
#    SetHandler application/x-httpd-php-source
#</FilesMatch>

#
# Apache specific PHP configuration options
# those can be override in each configured vhost
#
#php_value session.save_handler "files"
#php_value session.save_path    "/var/lib/php/session"
```

変更点は以下の通りです。

1. `.php` のファイルが `application/x-httpd-php` ハンドラーに割り当てられているため、`php54-cgi` ハンドラーに割り当てる。(`.phps` も同じように割り当てる)
2.  `php54-cgi` ハンドラーがリクエストされた際に`/cgi-bin/php54`を呼び出すようにする。

## cgi バイナリの配置
php.conf に記述した `/cgi-bin/php54` を配置します。
まずは、httpd.conf で cgi バイナリを配置するディレクトリを確認します。

```:/etc/httpd/conf/httpd.conf
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
```

`/var/www/cgi-bin` に配置すればよいことがわかりました。

また、cgi バイナリの場所も確認します。

```
which php-cgi
/usr/bin/php-cgi
```

シンボリックリンクで cgi バイナリを配置します。

```
cd /var/www/cgi-bin/
ln -s /usr/bin/php-cgi php54
```

## シンボリックリンクを許可する設定
シンボリックリンクで cgi バイナリを配置しているので、シンボリックリンクを許可する設定を
 httpd.conf に記述します。

```:/etc/httpd/conf/httpd.conf
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options FollowSymLinks
    Require all granted
</Directory>
```

## CGI の使用を許可する設定
今回はデフォルトのドキュメントルート`/var/www/html`を使用するので、このディレクトリに設定します。

`Options FollowSymLinks Includes ExecCGI` を記述しています。

```
<Directory "/var/www/html">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options FollowSymLinks Includes ExecCGI

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>
```

## CGIで動いているか確認
最後にブラウザでURLを入力して、以下のような表記がされていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184532/8bff864a-f96e-0ef1-3f08-649bd7547bbb.png)

## 最後に
今回は勉強として、php を CGI で動かしてみました。
次はもっと実用的な php-fpm を使って記事にします。

最後まで読んでいただきありがとうございました。