IDCFクラウドを用いてざっくりとHTTP/2に対応させる


この記事は、本来お蔵入りになる予定の記事でしたが、『overwrite』（上書きする）という項目がちらっと見えたので、蔵から出すことにしました。

ポストしている日がクリスマスというのはお察しですが、IDCFクラウド Advent Calendar 23日目を担当します。

お約束ですが、[前回までの環境から](http://qiita.com/nasa114/items/57cff01bebef07a66e9f)の続きです。

## HTTP/2とは

普段、私達がブラウザから見ている情報を配信するための通信プロトコルです。簡単に言うと、SSHやFTPなどと同じ類のものだと思ってください。

今まではHTTP/1.0でしたが、HTTP/2.0と呼ばれる新しいバージョンが正式に発表されました。時代背景などに関しては、以下の記事に詳しく書かれています。

* [「HTTP/2」がついに登場！ 開発者が知っておきたい通信の仕組み・新機能・導入方法 (1/3)：CodeZine（コードジン）](http://codezine.jp/article/detail/8663)


## HTTP/2にはApacheでは対応が難しい

Apacheで対応するには、2.4.17以降のバージョンが必要になります。

> An official Apache httpd module, first released in 2.4.17. See Apache downloads to get a released version.

* [icing/mod_h2](https://github.com/icing/mod_h2)

makeしてしまえば〜というは後々を考えるとメンテナンスに時間がかかってしまいます。

実質、Apacheで対応することはほぼ不可能に近いといっても過言ではありません。となれば、一つ思いつくのが「ウェブサーバーを変えてしまえば良いのでは」ということ。

[nginxが最近対応したらしい](https://www.nginx.com/blog/nginx-1-9-5/)ので、nginxを使って対応させます。

## 今回の目標地点

前置きが長かったですが、「ウェブサーバーでphpが動く環境（Linux, nginx, php, MySQL）」を構築することを目標とします。

なお、MySQLは[前の前の環境構築で構築したはず](http://qiita.com/nasa114/items/ef73a7b80984fc092de9)なので、割愛します。

## nginxを導入する

nginxを導入するための方法はざっくりと分ければ2通りです。

* コンパイルする（make install）
* rpmを取得する
	* wgetを用いる方法
	* yumを用いる方法
		* 今まで用いているレポジトリを利用
		* **nginx側でPre-buildしているものを利用**

apt-getとか知らない子です。「IDCFクラウドでざっくりと〜」シリーズの冒頭で記載したとおりですので。

> **Ubuntuは苦手なので。**

* [IDCFクラウドでざっくりとa-blog cmsを構築する - Qiita](http://qiita.com/nasa114/items/ef73a7b80984fc092de9)

ということで、nginxのレポジトリを導入します。レポジトリにも2種類あります。

* Stable Version
* Mainline Version

簡単に言うと、前者は保守的な感じで、後者は変化を望む人向け…ということらしいです。あまり良くわかっていませんが。バージョンが0.1異なるのですが、新機能が追加されるのは後者なので、個人で利用するのであれば後者で良いと思います。

### nginxのレポジトリを登録する
``vi /etc/yum.repos.d/nginx.repo``で編集します。

```/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
```

自動更新を希望しない場合は`enabled=0`に変更してください。

インストールをするには、以下のコマンドでいけます。

```
# nginx.repoをenabled=1の場合
yum install nginx
# nginx.repoをenabled=0の場合
yum install nginx --enable-repo=nginx
```
インストールが特に問題ない時には、最後に `-y` を追加してしまえばコーヒーをいれている間にインストールが完了します。

### php-fpmをインストールする

nginxは、高速な処理能力やプロキシ能力を持っている反面、Apacheのように単体でphpなどを実行することができません。phpを実行できないため、phpをFastCGIで実行する必要があります。

今回は、定番ともいえる php-fpm をインストールします。

```
yum install php-fpm
```

## nginxに最適な設定をする

nginxで運用するために最適な設定をする必要があります。

### php-fpmの設定をする

php-fpmの設定はそこまで難しくありません。

```/etc/php-fpm.d/www.conf
; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('www' here)
[www]

; Per pool prefix
; It only applies on the following directives:
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or @php_fpm_prefix@) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx
```

userとgroupをnginxに変更して、保存します。他の部分は変更する必要はありません。

### nginxの設定をする

nginxの設定はデフォルトのままでも良いとは思います。

VirtualHostsの設定を書き換えます。今回、ドメインとディレクトリを以下の前提で記述しています。

* ディレクトリ: /var/www/ac2015
* ドメイン: ac2015.arealv.net

```/etc/nginx/conf.d/ac2015.conf
server {
    listen       443 ssl http2;
    server_name  ac2015.arealv.net;

    location / {
        root   /var/www/ac2015;
        index  index.php index.html index.htm;
        # PicoやWordPress系のrewriteが必要なもの
        if (!-e $request_filename) {
            rewrite ^(.+)$  /index.php?q=$1 last;
        }
    }

    ssl_certificate /etc/letsencrypt/live/ac2015.arealv.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ac2015.arealv.net/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # openssl dhparam -out dhparam.pem 2048
    ssl_dhparam /etc/nginx/dhparam.pem;

    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security max-age=31536000;

    ssl_stapling on;
    ssl_stapling_verify on;


    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }


    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        # DocumentRootを設定する
        root           /var/www/ac2015;
        fastcgi_pass   127.0.0.1:9000;
        #fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
```

`/etc/nginx/conf.d/default.conf`を参考に設定しています。

標準の部分から変更したのは、以下の箇所。

* 3行目 `listen       443 ssl http2;` → SSL通信をサポートし、HTTP/2を用いた通信をサポートすることを宣言
* 4行目 →　運用するドメインを記載する
* `location ~ \.php$ {`内の`root`項目 → DocumentRootを宣言する
* 上記の`fastcgi_param` → `SCRIPT_FILENAME  $document_root$fastcgi_script_name;`に変更することによって、DocumentRootを正しく認識させる

追加したのは、SSLの設定です。SSL設定をまるっとコピーしても良いとは思いますが、SSLの認証鍵などに関しては割愛します。（このシリーズではLet's Encryptを利用しているので、ドメインを書きなおせば良いと思います。SSL部分の設定はMozillaを参考にしました）

## 実際に起動する

```
systemctl start php-fpm
systemctl start nginx
systemctl enable php-fpm
systemctl enable nginx
```

そして、ウェブディレクトリに以下のphpを設置すれば良いと思います。

```/var/www/ac2015/demo.php
<?php phpinfo(); ?>
```

ac2015部分は各自の環境に合わせてください。

これで、こなれたphpinfoの画面が出てくれば成功です。

## 確認するには？

確認するには、Chromeを用いるのがベストだと思います。[HTTP/2 and SPDY indicator - Chrome ウェブストア](https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=ja)をインストールします。

サイトにアクセスした時にアドレスバーに稲妻マークがついていれば、成功です。

今回、利用したドメイン[ac2015.arealv.net](https://ac2015.arealv.net/)を確認用に当面は利用できるようにしています。php製のCMS[Pico](http://picocms.org/)を利用しています。

![参考画像](https://qiita-image-store.s3.amazonaws.com/0/98020/c9d05c19-eb2b-9521-1cce-0cef74e98970.png)