初心者がAWS(EC2)にアプリをデプロイする際に対峙したエラーとその対応

# はじめに
デプロイの際に遭遇したエラーたちとの奮闘記です。
まとまってませんが、皆さんのエラー解決のヒントになれば幸いです。

# Version等
Ruby:　2.3.1
Rails:　5.0.1
AWS(EC2)・Nginx・Unicorn・Mysqlの組み合わせ。

# ①　rails コマンドが使えない
```:terminal
[ec2-user@ip-XXX-XX-XX-XXX teatapp]$ rails secret
-bash: rails: コマンドが見つかりません
```
### 解決策
exitで一回ec2を出て入り直すとコマンドが使えるようになる。
なんか変なこと起きたらとりあえず再起動しよう。ド初歩　...。

# ②　Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
「'/tmp/mysql.sock'のソケットじゃ、MySQLと通信できません」とのエラー。アプリケーションが指定しているソケットと、データベース側のソケットが食い違っているために通信ができない模様。
ソケットに関しては以下でざっくり掴めると思います。
[IT用語辞典e-Words](http://e-words.jp/w/%E3%82%BD%E3%82%B1%E3%83%83%E3%83%88.html)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](http://wa3.i-3-i.info/word168.html)

```:terminal
$ mysql_config --socket
```
このコマンドでmysql側のソケットタイプが調べられるので調べてみると、

```:terminal
[ec2-user@ip-XXX-XX-XX-XXX ~]$ mysql_config --socket
/var/lib/mysql/mysql.sock
```
`/var/lib/mysql/mysql.sock`こういうタイプのソケットらしい。
一方、アプリ側のソケットを調べてみると、

```:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password:
  socket: /tmp/mysql.sock
```
`/tmp/mysql.sock`と、Mysql側のソケットとタイプが異なる。

### 解決策
ということでアプリ側のソケットの記述を以下のように修正。

```:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password:
  socket: /tmp/mysql.sock

 （中略）

production:
  <<: *default
  database: testapp_production
  username: testapp
  password: <%= ENV['TESTAPP_DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock
```

default部分の記述は残したままで、productionの方に加筆すればOK。
これで、ソケットタイプが合致してアプリとデータベースが通信できるようになりました。

と、思いきや

# ③ ERROR -- : Access denied for user 'testapp'@'localhost' (using password: NO) (Mysql2::Error)

```:terminal
[ec2-user@ip-XXX-XX-XX-XXX testapp]$ unicorn_rails -c config/unicorn.rb -E production
```
のコマンドでunicornを作動しても、うまく立ち上がらず。

何が起こっているのか、エラーの詳細を確認するために、以下のコマンドを実行。

```:terminal
[ec2-user@ip-XXX-XX-XX-XXX testapp]$ less log/unicorn.stderr.log
```
`log/unicorn.stderr.log`のログを辿ると、以下のような記述が。

```:log/unicorn.stderr.log
ERROR -- : Access denied for user 'testapp'@'localhost' (using password: NO) (Mysql2::Error)
```

using password: NOということで、どうやら環境変数で設定したパスワードが読み込まれていない模様。
①アプリ側の環境変数を読み込んでいるところの記載
②EC2側の環境変数を書き込んでいるところの記載
をチェックしてみると...

```:database.yml
production:
  <<: *default
  database: testapp_production
  username: testapp
  password: <%= ENV['TESTAPP_DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock
```

アプリ側は、`password: <%= ENV['TESTAPP_DATABASE_PASSWORD'] %>`との記述。
一方EC2側はの記載を以下のコマンドでチェックしてみると、

```:terminal
$ sudo vim /etc/environment
```

```:etc/environment
DATABASE_PASSWORD='XXXXXXXXXXXXXXX'
SECRET_KEY_BASE='XXXXXXXXXXXXXXX'
```

`DATABASE_PASSWORD='XXXXXXXXXXXXXXX'`との記述。

変数がアプリ側とEC2側で食い違ってました。

### 解決策

ということで、アプリ側の記述を以下のように変更。

```:database.yml
production:
  <<: *default
  database: testapp_production
  username: testapp
  password: <%= ENV['DATABASE_PASSWORD'] %> 　 # 「TESTAPP_」を削除
  socket: /var/lib/mysql/mysql.sock
```

これで環境変数が正しく読み込まれるようになりました。
ちなみにですが、
___① Mysqlのroot user passwordの先頭が「0」で始まる場合、環境変数の読み込みがうまくいかない場合がある___
___② 環境変数名に「-」（ハイフン）を含めると、環境変数の読み込みがうまくいかない場合がある___
みたいです。

環境変数を

```:etc/environment
NEW-APP_DATABASE_PASSWORD='01234567'
SECRET_KEY_BASE='XXXXXXXXXXXXXXX'
```
のように変数名にハイフンを含めており、パスワードの先頭を0で始めていて、大っ変痛い目に会いました。

ちなみのちなみに、環境変数がちゃんと読み込まれているか確認するには、

```:terminal
[ec2-user@ip-XXX-XX-XX-XXX testapp]$ rails c
```
でコンソールを開いて、

```:terminal
irb(main):001:0> ENV['DATABASE_PASSWORD']
=> "XXXXXXXX"

```
と環境変数を打ってあげればちゃんと読み込めているか確認できます。



さて、これでunicornが使えるかと思いきやまたMysqlのエラー。

# ④ ERROR -- : Access denied for user 'testapp'@'localhost' (using password: YES) (Mysql2::Error)

ソケットも合わせて、
環境変数も読み込めるようにして、
でもエラー。エラー文を見てみると、なんかユーザーのところが「testapp」になっている。ここが原因。

```:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password:
  socket: /tmp/mysql.sock

 （中略）

production:
  <<: *default
  database: testapp_production
  password: <%= ENV['TESTAPP_DATABASE_PASSWORD'] %>
                       　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　# productionのuser部分を削除。
  socket: /var/lib/mysql/mysql.sock
```

### 解決策
productionのuser部分を削除（するとdefaultのusername、つまりrootがproductionでも読み込まれるようになる）。

これで、

```:terminal
$ unicorn_rails -c config/unicorn.rb -E production
```

をしてあげるとunicornが立ち上がりました。Mysqlとの通信もうまくいっている模様。でも、

# ⑤ Unicornは動いているのにページが表示されない

http:// ~Elastic IP~ :3000/でページにアクセスしても、ロードが続くだけで表示されず。

<img width="444" alt="スクリーンショット 2017-02-16 18.28.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/158026/faa673d6-f78e-8143-0533-483e50bfc491.png">

と出てきてしまう。ううう...。

これは原因は単純でポートの開け忘れでした。

<img width="1240" alt="スクリーンショット 2017-02-16 18.29.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/158026/1d075224-fcbc-7635-1cdb-42e3ee538391.png">

AWSでポート3000を開けてあげて、

ページが表示されました。


# 参考サイト

[IT用語辞典e-Words](http://e-words.jp/w/%E3%82%BD%E3%82%B1%E3%83%83%E3%83%88.html)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](http://wa3.i-3-i.info/word168.html)