AWSのEC2でUbuntu+nginx+php-fpmの環境構築物語

## 概要

サーバ構築に慣れようと思ってAWSのEC2を利用してUbuntu, php7.0, php-fpm, nginxの環境を構築しました

```
OS:
　　　　Linux version 4.4.0-62-generic (buildd@lcy01-30) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017
php(php-fpm):
　　　　PHP 7.0.15-1+deb.sury.org~xenial+1 (cli) (built: Jan 20 2017 08:53:13) ( NTS )
nginx:
　　　　nginx version: nginx/1.10.0 (Ubuntu)
```

参考にしたものは以下の２つのqiita
簡潔なものと、詳細なものという感じ

[nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する](http://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)
[EC2にnginx+php(php-fpm socket)環境を最速で構築](http://qiita.com/koni/items/05158e33b4c8aac07b59)


## EC2インスタンス作成

AWSのEC2インスタンスを作成します。今回はUbuntuでの環境構築です。
AWSのサイトでインスタンスを作成すると自分のPCにはpemファイル(プライベートキーファイル)が作成されます。
これを使ってSSH接続が可能です。（hogeの部分は自分で設定したものになります）

`ssh -i "hoge.pem" ubuntu@ec2-XX-XXX-XX-XXX.us-west-2.compute.amazonaws.com`
（AWSのサイトでインスタント接続のページを開くと、コマンドは用意してくれてます）

ちなにみ僕はそのままやったら.pem.txtの拡張子になったので"hoge.pem.txt"を指定してそのまま使ってます。

 > __※ハマりポイント__
 > セキュリティグループに自分のIPアドレスからのSSHアクセスを許可して上げないといけない
 > インバウンドの「編集」から、「ルールの追加」をしてあげる
 > SSH(port22)とHTTP(port80)を設定いし、送信元を”マイIP”にする
 > 複数の登録も可能である

## 初期設定

サーバで基本的な設定を行います。初期設定はEC2に限ったものではないです。
初回ログインをすると、ubuntuユーザになってます。

#### rootログインの禁止、ポート変更

`ubuntu@ip-XXX-XX-XX-XXX:~$ sudo vim /etc/ssh/sshd_config`

二箇所変更する

```
# What ports, IPs and protocols we listen for
- Port 22
+ Port 50022
...
# Authentication:
LoginGraceTime 120
- PermitRootLogin prohibit-password
+ PermitRootLogin no
StrictModes yes
```

 > __※ハマりポイント__
 > ここでポートを変更したらAWSのサイトでもう一度セキュリグループの設定が必要です
 > タイプを「カスタムTCP」に設定、ポート番号を任意のものにします

## 作業ユーザ作成とパスワード設定

```
ubuntu@ip-XXX-XX-XX-XXX:~$ sudo useradd sasaki
ubuntu@ip-XXX-XX-XX-XXX
:~$ sudo passwd sasaki
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

ubuntuはデフォルトの初期ユーザなので、作業用ユーザでログインができたらubuntuさんは削除しちゃっていいと思います

## php-fpmとnginxの導入

apt-getを用いてインストールしていきます
MySQLが必要な人はここで`$ sudo apt-get install php7.0-mysql`も叩いてあげましょう

```
$ sudo apt-get install php7.0-fpm
$ sudo apt-get install php7.0
$ sudo apt-get install nginx
```

#### バージョン確認


```
$ sudo php-fpm7.0 -v
PHP 7.0.15-1+deb.sury.org~xenial+1 (fpm-fcgi) (built: Jan 20 2017 08:53:13)
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.15-1+deb.sury.org~xenial+1, Copyright (c) 1999-2017, by Zend Technologies
$ sudo nginx -v
nginx version: nginx/1.10.0 (Ubuntu)
```

## php-fpmとnginxの設定

まずはphp-fpmから、次にnginxやりました

php-fpmとnginx間のやり取りはTCPを用いる方法とUNIXドメインソケットを用いる方法があります
今回はスループットの優れているUNIXドメインソケットでの通信を用いることにしました

#### php-fpm

`$ vi /etc/php/7.0/fpm/pool.d/www.conf`

nginxと同じにする必要があるためuserとgroupを確認しておく、今回のデフォルトはwww-data

```/etc/php/7.0/fpm/pool.d/www.conf
user = www-data
group = www-data
```

UNIXドメインソケットを用いるための設定を行う
127.0.0.1:9000はTCP用の設定

```/etc/php/7.0/fpm/pool.d/www.conf
- listen = 127.0.0.1:9000
+ listen =  /var/run/php-fpm/php-fpm.sock
```

 > __※ハマりポイント__
 > ユーザ名、グループ名、listenの内容はphp-fpmと揃える
 > php-fpmとnginx間の接続がうまくいかない場合ここが間違ってる可能性を疑う


#### nginx

php-fpmと同じようにユーザ名を確認する
一番上に記載されている

```/etc/nginx/nginx.conf
user www-data;
```

`/etc/nginx/conf.d`が設定ファイル、ここではconf.d/*.confを読み込む用設定してあるためfpmとの設定用のファイルをここに作成する

```
# vi /etc/nginx/conf.d/server.conf
```

`fastcgi_pass`に記載する内容がphp-fpm側の設定の`listen`に対応する


```/etc/nginx/conf.d/server.conf

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm;
        server_name localhost;

        location / {
                if (-f $request_filename) {
                        expires 30d;
                        break;
                }
        }

        location ~ [^/]\.php(/|$) {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
                include fastcgi_params;
        }
}
```


また、デフォルトでincludeされているsites-enabledを呼ばないようにする

```/etc/nginx/nginx.conf
#include /etc/nginx/sites-enabled/*;
```

> __※ハマりポイント__
> include /etc/nginx/sites-enabled/*が行われると今作成したphp-fpmとの接続の設定が効かなくなる
> 僕はphpファイルがそのままダウンロードされたところでしばらく詰まった、これが原因だった

#### 起動


```
$ sudo service php7.0-fpm start
$ sudo service nginx start
```

起動するとphp-fpmのsocketファイルが作成されているはずである

`$ cat /var/run/php/php7.0-fpm.sock`

 > __※ハマりポイント__
 > これらの設定をファイルを変更したらrestart及びreloadをしないと変更は反映されない
 > 意外と、結構忘れがちなので注意する
 >
 > sudo service php7.0-fpm reload
 > sudo service nginx reload
 >

#### UNIXドメインソケットによる通信ができているか確認する

```
$ netstat -a --unix
...
unix  2      [ ACC ]     STREAM     LISTENING     490025   /var/run/php/php7.0-fpm.sock
...
```

## 表示を確認する

server.confに設定したルートディレクトリに適当なphpファイルを置く

```/var/www/html/hoge.php
<?php
  echo 'Hello, php-fpm.'
```

ブラウザで確認する、割り振られたパブリックIPにアクセス

`http://XX.XXX.XX.XXX/hoge.php`

これで「Hello, php-fpm.」が確認できれば設定は完了、お疲れ様でした。

## 困ったら

#### ログを見る

```/etc/nginx/nginx.conf
access_log /var/log/nginx/access.log;
- error_log /var/log/nginx/error.log;
+ error_log /var/log/nginx/error.log debug;
```

これでエラーログがデバッグ用に色々書いてくれるようになる

#### netstatコマンドでネットワークの状態を確認できる

```
$ netstat -a --unix
...
unix  2      [ ACC ]     STREAM     LISTENING     490025   /var/run/php/php7.0-fpm.sock
...
```


## あとがき

AWSも初めて利用する場合は戸惑うところがある、少し学ぶ時間が必要だと思っといた方がいい。
セキュリティグループの下りも見つけるの時間かかった。
設定がグチャグチャして来たら殺して新しいインスタンス立ててやり直した方が早そう。

restartしてくれない、みたいなことも起こった

```
$ sudo service nginx restart
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
```

言われた通りに"systemctl status nginx.service" and "journalctl -xe"を見に行くと、設定ファイルのsyntaxエラーだったりした。

一番詰まったのは何より`include /etc/nginx/sites-enabled/*`
何度設定を確認してもphpファイルがダウンロードされるだけで進めなかったし、エラーログでもわかりづらい