AWS EC2 + nginx + Laravel + RDS(PostgreSQL)の環境を構築する

## 本記事の対象者

- AWS上でLaravel + PostgreSQLを動かしてみたい人
- ついでにnginxに少し触れてみたい人

## 全体の流れ

1. EC2インスタンスを作成してSSH接続する
2. nginxをインストールして起動する
3. PHPをインストールしてphpinfoを表示する
4. Composerをインストールする
5. Laravelのウェルカムページを表示する
6. RDS(PostgreSQL)を作成する
7. EC2からpsqlでRDSに接続する
8. DBのマイグレーションを行う
9. Laravelのログイン機能でDBとの接続を確認する
10. トラブルシューティング
11. 補足

## 環境

- Amazon Linux 2
- nginx 1.12
- php7.3
- Laravel 6.4.1
- PostgreSQL 9.6

## 1. EC2インスタンスを作成してSSH接続する

以下のEC2インスタンスを作成します。

- AMI : Amazon Linux 2 AMI (64 ビット x86)
- インスタンスタイプ : t2.micro
- インスタンスの詳細の設定はデフォルト
    - 自動割り当てパブリック IPは`サブネット設定を使用(有効)`
- セキュリティグループに以下を追加
    - タイプ : HTTP
    - ソース : 0.0.0.0/0

EC2インスタンスにSSH接続します。

```
$ ssh ec2-user@(EC2のパブリックIP) -i ~/.ssh/yourkey.pem
```

yum updateしておきます。

```
$ sudo yum update -y
```

## 2. nginxをインストールして起動する

nginxをインストールします。

```
$ sudo amazon-linux-extras install nginx1.12 -y
```

nginxを起動します。

```
$ sudo systemctl start nginx
```

ブラウザで、EC2のパブリックIPにアクセスすると、`Welcome to nginx on Amazon Linux!`の画面が表示されます。

## 3. PHPをインストールしてphpinfoを表示する

PHPをインストールします。

```
$ sudo amazon-linux-extras install php7.3 -y
```

`nginx.conf`を見ると、ドキュメントルートが`/usr/share/nginx/html`であることがわかります。

```
$ vi /etc/nginx/nginx.conf
```

```:/etc/nginx/nginx.conf
## 略
    server {
        # 略
        root         /usr/share/nginx/html;
```

このドキュメントルート配下に、PHPファイルを配置します。

```
$ sudo vi /usr/share/nginx/html/info.php
```

```php:/usr/share/nginx/html/info.php
<?php phpinfo(); ?>
```

ただし、この段階では、ブラウザで`EC2のパブリックIP/info.php`にアクセスすると、phpinfoの結果が表示されるのではなく、`info.php`がダウンロードされてしまいます。

そこで、`/etc/php-fpm.d/www.conf`を以下の通り編集します。

```
$ sudo vi /etc/php-fpm.d/www.conf
```

```:/etc/php-fpm.d/www.conf
user = nginx # apacheであったのをnginxに
group = nginx # 同上
```

その後、nginxを再起動します。

```
$ sudo systemctl restart nginx
```

ブラウザで`EC2のパブリックIP/info.php`にアクセスすると、phpinfoの結果が表示されます。

# 4. Composerをインストールする

Composerをインストールします。

```
$ cd ~
$ sudo curl -sS https://getcomposer.org/installer | php
$ sudo chown root:root composer.phar
$ sudo mv composer.phar /usr/bin/composer
```

Composerが起動することを確認します。

```
$ composer 
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
```

## 5. Laravelのウェルカムページを表示する

あらかじめ`php-mbstring`と`php-xml`をインストールしておきます。

これをやっておかないと、Laravelのインストールが失敗します。

```
$ sudo yum install php-mbstring php-xml -y
```

Laravelをインストールします。

```
$ sudo mkdir /var/www
$ cd /var/www
$ sudo composer create-project --prefer-dist laravel/laravel
```

Laravelのインストールに伴って、nginx.confを編集します。

```
$ sudo vi /etc/nginx/nginx.conf
```

```:/etc/nginx/nginx.conf
# 略
    server {
        # 略
        root         /var/www/laravel/public; # ここを修正
# 略
        location / {
             try_files $uri $uri/ /index.php$is_args$args; # ここを追加
        }
```

try_filesディレクティブでの、

- `$uri $uri/ /index.php$is_args$args;`

は、

>1. URLのパスにファイルが存在するか？
>2. 1 がなかった場合、URLのパスにディレクトリが存在するか？
>3. 1も2もなかった場合、指定したロケーションにリダイレクトする。

といった処理になります。

- [参考 : nginxの設定 - bnote.net](https://www.bnote.net/centos/nginx_conf03.html)

編集後、nginxを再起動します。

```
$ sudo systemctl restart nginx
```

storage/ディレクトリの権限を変更します。

```
$ cd /var/www/laravel
$ sudo chmod -R 777 storage/
```

ブラウザで`EC2のパブリックIP`にアクセスすると、Laravelのウェルカムページが表示されます。

## 6. RDS(PostgreSQL)を作成する

以下のRDSを作成します。

- 作成方法 : 標準作成
- エンジンのタイプ : PostgreSQL
- バージョン : PostgreSQL 9.6.x
- テンプレート : 無料利用枠
- DB インスタンス識別子 : お好みで
- マスターユーザー名 : postgres
- パスワードの自動生成 : お好みで
- DBインスタンスサイズ : 無料利用枠
- DB インスタンスサイズ : db.t2.micro
- データベース認証 : パスワード認証
- 最初のデータベース名 : お好みで

## 7. EC2からpsqlでRDSに接続する
 
`yum search postgresql`を実行すると、

```
postgresql.x86_64 : PostgreSQL client programs
```

と、PostgreSQLのクライアントが見つかるので、これをインストールします。

```
$ sudo yum install postgresql.x86_64 -y
```

また、RDSに割り当てられているセキュリティグループのインバウンドを編集し、EC2からポート5432で接続できるようにしておきます。

準備ができたので、EC2からRDS(PostgreSQL)に接続します。

```
$ psql -h (RDSのエンドポイント) -U postgres -d (RDS作成時の`最初のデータベース名`)
```

```
ユーザ postgres のパスワード:(RDS作成時に指定or自動作成したパスワード)
```

接続できることを確認できたら、`\q`で抜けます。

## 8. DBのマイグレーションを行う

`yum search postgresql`を実行すると、

```
php-pgsql.x86_64 : A PostgreSQL database module for PHP
```

が見つかるので、これをインストールします。

```
$ sudo yum install php-pgsql.x86_64 -y
```

laravelの.envファイルにRDSへの接続情報を入力します。

```
$ cd /var/www/laravel
$ sudo vi .env
```

```:.env
DB_CONNECTION=pgsql
DB_HOST=(RDSのエンドポイント)
DB_PORT=5432
DB_DATABASE=(RDS作成時の`最初のデータベース名`)
DB_USERNAME=postgres
DB_PASSWORD=(RDS作成時に指定or自動作成したパスワード)
```

マイグレーションを実行します。

```
$ php artisan migrate
```

以下が表示されたら成功です。

```
Migration table created successfully.
```

## 9. Laravelのログイン機能でDBとの接続を確認する

Laravel標準のログイン機能を作成します。

```
$ cd /var/www/laravel
$ sudo composer require laravel/ui
$ sudo php artisan ui vue --auth
$ curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -
$ sudo yum install -y nodejs
$ sudo npm install
$ sudo npm run dev
```

LaravelのウェルカムページにREGISTER, LOGINが表示されるので、それらから正常にユーザー登録やログインが実施できることを確認してください。

以上で、ハンズオンは終了です。

## 10. トラブルシューティング

### EC2にSSH接続できない

鍵のパーミッションが644等であれば、600に変更してください。

```
$ chmod 600 ~/.ssh/yourkey.pem
```

### composer updateがエラーになる

`Cannot allocate memory`が出てエラーになるようであれば、以下を参考にしてみてください。

- [Composerでメモリエラーが発生したときの対処方法【詳細解説】](https://evisu0414.com/engineer/engineer010/)

### Laravel標準のLOGIN, REGISTERを実施しようとすると`could not find driver`のエラーになる

php-fpmを再起動してみてください。

```
$ sudo systemctl restart php-fpm
```

## 11. 補足

Laravelをインストールするのではなく、既存の適当なLaravelアプリケーションを使いたい人は、`5. Laravelのウェルカムページを表示する`の代わりに、

```
$ sudo yum install git -y
```

でGitをインストールして、git cloneするなどしてください。

## 参考

- [nginxの設定 - bnote.net](https://www.bnote.net/centos/nginx_conf03.html)

- [Laravel6.0「make:Auth」が無くなった 〜Laravel6.0でのLogin機能の実装方法〜MyMemo - Qiita](https://qiita.com/daisu_yamazaki/items/a914a16ca1640334d7a5)