【Rails】EC2上でのbundle install時のメモリ不足のエラーと解消方法


DockerでRailsのコンテナを`Run`する際に、`bundle install`と`yarn install`を起動させているのですが、`Gem::Ext::BuildError: ERROR: Failed to build gem native extension.`といったエラーが発生しました。

```
web_1    | Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
web_1    | 
web_1    | current directory:
web_1    | /app/vendor/bundle/ruby/2.7.0/gems/racc-1.5.2/ext/racc/cparse
web_1    | /usr/local/bin/ruby -I /usr/local/lib/ruby/2.7.0 -r
web_1    | ./siteconf20210129-9-ef1ov1.rb extconf.rb
web_1    | extconf failedOut of memory - /usr/local/bin/ruby
web_1    | 
web_1    | Gem files will remain installed in /app/vendor/bundle/ruby/2.7.0/gems/racc-1.5.2
web_1    | for inspection.
web_1    | Results logged to
web_1    | /app/vendor/bundle/ruby/2.7.0/extensions/x86_64-linux-musl/2.7.0/racc-1.5.2/gem_make.out
web_1    | 
web_1    | An error occurred while installing racc (1.5.2), and Bundler cannot continue.
web_1    | Make sure that `gem install racc -v '1.5.2' --source 'https://rubygems.org/'`
web_1    | succeeds before bundling.
web_1    | 
web_1    | In Gemfile:
web_1    |   rails was resolved to 6.0.3.4, which depends on
web_1    |     actioncable was resolved to 6.0.3.4, which depends on
web_1    |       actionpack was resolved to 6.0.3.4, which depends on
web_1    |         actionview was resolved to 6.0.3.4, which depends on
web_1    |           rails-dom-testing was resolved to 2.0.3, which depends on
web_1    |             nokogiri was resolved to 1.11.0, which depends on
web_1    |               racc
web_1    | 
web_1    | 
web_1    | Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
web_1    | 

〜〜〜 以下、他のGemでも同様のエラー　〜〜〜

web_1    | 
web_1    | In Gemfile:
web_1    |   mysql2
web_1    | !! exit status 5
```

##原因
EC2上でのメモリ不足でした。
AWSの無料利用枠の対象であるt2.microはRAMが1GBしかなく、そりゃ足りないよねといった状態でした。

##解決方法
以下の通りメモリスワップさせ、記憶できる容量を1GB→3GBに増やしたところ、`bundle install`と`yarn install`が正常に完了しました。

```shell:SSHでEC2にログイン
$ sudo dd if=/dev/zero of=/swapfile bs=16M count=128    #スワップ用のファイル作成
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile    # スワップ領域の作成
スワップ空間バージョン 1 を設定します。サイズ = 2 GiB (2147479552 バイト)
ラベルはありません, UUID=a0628f7c-7088-4829-9258-e533a2b067f6
$ sudo swapon /swapfile    # スワップ領域を有効化する
$ sudo swapon -s           # スワップ設定内容の確認
ファイル名				タイプ		サイズ	使用済み	優先順位
/swapfile                              	file    	2097148	0	-2
$ sudo vi /etc/fstab
```

```:fstabにvimで新たな行として追記
/swapfile swap swap defaults 0 0
```
###ddコマンド
ファイルを変換してコピーする
`if=/dev/zero`：0埋め
`of=/swapfile`：作成対象のファイル名

`bs=16M`：1ブロックあたり16MB
`count=128`：128ブロック
　→約2GBをスワップ領域として確保。（最適な分け方かは不明。）

###スワップ領域の推奨サイズ
一般的な推奨されるスワップ領域は以下の通りです。
t2.microは1GBのため、2GB分作成しました。

|物理 RAM の量	|推奨されるスワップ領域
|---|---|
|2 GB 以下の RAM|RAM 容量の 2 倍、ただし常に 32 MB を超える
|2 GB 以上の RAM、ただし 32 GB 未満|4 GB + (RAM – 2 GB)
|32 GB 以上の RAM|RAM 容量の 1 倍

##スワップ領域の無効化
スワップ領域を無効化したい場合は、`swapoff`で可能です。

```shell:SSHでEC2にログイン
$ swapon -s
ファイル名				タイプ		サイズ	使用済み	優先順位
/swapfile                              	file    	2097148	90368	-2
$ sudo swapoff /swapfile
$ swapon -s
〜〜〜　何も表示されない　〜〜〜
```

##参考記事
**・[スワップファイルを使用して Amazon EC2 インスタンスでスワップ領域としてメモリを割り当てる](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-memory-swap-file/)**
**・[linux スワップ（swap）領域の作成](https://kazmax.zpp.jp/linux_beginner/mkswap.html)**