【Rails】Capistrano 自動デプロイの際、色々はまったのでメモ（随時更新予定）

## はじめに
bundle exec cap production deploy コマンドを叩いた際の
個人的なエラー対応備忘録ですが、
同じように悩んでいる方の一助になれたら嬉しく思います。

## 概要/背景
- 某フリマサービスのクローンを作成する。
- レビューはメンターが行い、LGTMをもらい次第、Mergeしていく
- GihHub Flow に従い、masterブランチは常にデプロイできる状態とする
- 上記の前提を踏まえ、Capistrano を使って自動デプロイを行う際にエラー対応したものを、記録としてまとめておくもの（随時更新予定）

## 環境
Rails 5.0.7.2
Ruby 2.3.1
MySQL 5.6
macOS High Sierra
IaaS AWS(EC2)
Web Server Nginx
Application Server Unicorn

## エラー内容
- No space left on device
- Socket error関連
- using password: No
- bundle install がうまくいかない
- already exist 'hoge' table
- bundle stdout: Nothing written系


### No space left on device

```:ターミナル
cap aborted!

SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@xx.xxx.xxx.xxx: scp: /tmp/git-ssh-<リポジトリ名>-production-<ユーザー名>.sh: No space left on device

Caused by:
scp: /tmp/git-ssh-<リポジトリ名>-production-<ユーザー名>.sh: No space left on device
```



#### 対応内容

こちらの記事を参考にさせていただきました。
[AWSで「No space left on device」が出たときの対応]
(https://qiita.com/shizuma/items/64545f2e2037011647ae)

EC2側で
df -l で空き容量チェック

```:EC2
[ec2-user@ip-xxx-xx-xx-xx ~]$ df -l

Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          494128      60    494068   1% /dev
tmpfs             504712       0    504712   0% /dev/shm
/dev/xvda1       8123812 8023916         0 100% /
```

USE％の部分が100%なっておりました。

で、どこがそんなに容量食っておるんや、と
$ du -h を叩くと

```:EC2
5.2G	./shared/log
5.3G	./shared
```

と、5GB超えていた。
rm コマンドで
全ての log (production, capistrano.stderr, capistrano.stdout) を削除。
その後、$ sudo service mysqld restart すると、production.log は自動で作成される。
capistrano.stderr.log, capistrano.stdout.log は自動復活しないので、
$ sudo touch コマンドで作成する。

#### 気づき
おそらく production.log のみの削除でよかったかも。
（2019.3.22追記： production.logのみの削除で良かったです）

ちゃんとそれぞれのlogファイルのの容量見ておけばよかった。
あと、後ほど定期的にlogを削除するコマンドも実装しておく。


### ソケット関連

```:ターミナル
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
```

だったり、

```
Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
```

だったり、

```
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)
```


だったり、、途中 my.cnfを色々いじりすぎて分からなくなりかけました。。
が、下記対応内容で解決。

#### 解決策

以前の記事のようですが、参考にさせていただきました。

[「Can't connect to local MySQL server through socket」エラーについて]
(http://www.hi-ho.ne.jp/tsumiki/book_sup2.html)


まず、EC2側で、
$ mysql_config --socketを叩く

```:EC2
/var/lib/mysql/mysql.sock
```

となるので、
これをクライアント側に合わせる
$ sudo vi /etc/my.cnf　で
クライアント側の記述をする

```my.cnf
[client]
socket=/var/lib/mysql/mysql.sock

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
(mysqldの方はもともとこう記述されている)
```

また、ls コマンドで実際に sockファイルがあるかを確認し、
なければ、
$ sudo touch mysql.sockで sockファイルを作っておく
tmpの方もなかったので、作った。
permission deniedになるので所有者変更もする

```:EC2
$ sudo chown mysql:mysql /var/lib/mysql/mysql.sock
```

（理解を深める為、Socket Errorに関しては、再度あげなおす予定）

### using password: No

```:ターミナル
Mysql2::Error: Access denied for user 'root'@'localhost' (using password: NO)
```

#### 解決策
これは、EC2側で MySQLのroot passwordを設定しているので、
database.yml 側の defaultのpassword が空欄のため当然起こるもの。
EC2上でpasswordを直打ちはできないので、環境変数を利用し対応。
$ sudo vim /etc/environment で記述

```:etc/environment
DATABASE_PASSWORD= '任意のパスワード' 
SECRET_KEY_BASE='********************************************************************************************************************************'
```

ローカル側でdatabase.ymlのdefaultのpassword に環境変数を記述　

```:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /tmp/mysql.sock
```
これで解決。
（ただ、これが最適解ではないような気もしつつ）


### bundle install が失敗する

```:ターミナル
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
```

#### 解決策

この記事に助けられました。
[bundle installで躓いた話](https://qiita.com/HorikawaTokiya/items/9c18273e6d11a67ce1bd)
記事にならい、

```ruby:Gemfile
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

となっているのを、

```ruby:Gemfile
gem 'tzinfo-data'
```

のみにして bundle install

うまくいかなければ bundle update を叩くよう書かれていたので、
そのようにしたら、解決。
EC2側もで同様にbundle update 実施。
なので、ここでver. が上がっているgem がある旨チームメンバーに共有。


### already exists 'hoge' table
少し抽象度をあげますが、ある種のコンフリクト解消と思っていただければ。。

```:ターミナル
Mysql2::Error: Table 'users' already exists: CREATE TABLE `hoge` ...
```

#### 解決策

このエントリーにお世話になりました。
[rails generate migrationしてエラーが出たときの対処法](https://qiita.com/katsuyuki/items/5ba39293f16f5d6cbb56)

EC2側のMySQLにログイン 
$ mysql -u root -D <リポジトリ名>_production -p


show tables;
で hoges tableがある事を確認
drop table hoges;
で削除。
その後、
$ rake db:migrate:reset
( rake db:migrate  で全然良いです )

### bundle stdout: Nothing written系

```:ターミナル
cap aborted!

SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@xx.xxx.xxx.xxx: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
```

#### 対応内容

まず、lessコマンドでlogをみる

```:log/capistrano.stderr.log 
bundler: failed to load command: unicorn (/var/www/<リポジトリ名>/shared/bundle/ruby/2.3.0/bin/unicorn)
Errno::EACCES: Permission denied @ rb_sysopen - /var/www/<リポジトリ名>/shared/log/unicorn.stdout.log
```

との事だったので、
権限確認すると。。
なるほど、stdout 確かに r （読み込み）しかないね、となる。

```:EC2
[ec2-user@xxx-xx-xx-xx log]$ ls -l

total 16
-rwxr-xr-x 1 ec2-user ec2-user 9569 Mar 20 12:19 production.log
-rwxrwxrwx 1 root     root     3208 Mar 20 12:19 unicorn.stderr.log
-rw-r--r-- 1 root     root        0 Mar 19 18:30 unicorn.stdout.log
```

ゆえ、所有者変更。

```:EC2
$ sudo chown -R ec2-user:ec2-user /var/www/<リポジトリ名>/shared/log
```


所有者変更の反映を確認。
うまくいってる。

```:EC2
[ec2-user@ip-xxx-xx-xx-xx log]$ ls -l
total 16
-rwxr-xr-x 1 ec2-user ec2-user 9569 Mar 20 12:19 production.log
-rwxrwxrwx 1 ec2-user ec2-user 3208 Mar 20 12:19 unicorn.stderr.log
-rw-r--r-- 1 ec2-user ec2-user    0 Mar 19 18:30 unicorn.stdout.log
```


### 最後に

デプロイ周りでいつも時間を取られているので、
備忘録としてまとめております。
随時ブラッシュアップをかけていきます。