困ったことに、Railsアプリの本番環境で利用しているUnicornが起動しません。

ERROR -- : Cannot allocate memory - fork(2) (Errno::ENOMEM)

本番環境は下記の通りです。

環境
  • AWS EC2(t3.micro)
  • Rails 6
  • Nginx
  • Unicorn

翻訳してみると下記の通りです。

Cannot allocate memory = メモリを割り当てることができません

ということでgoogle先生に聞いてみると、分かりやすい記事がありました。

記事と同様に現状のメモリ使用状況について調査してみます。

ターミナル(ssh接続)

$ top
top - 21:31:53 up 70 days,  5:32,  1 user,  load average: 0.03, 0.01, 0.00
Tasks: 208 total,   1 running, 167 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.5 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.2 st
KiB Mem :   980012 total,    64996 free,   799364 used,   115652 buff/cache
KiB Swap:        0 total,        0 free,        0 used.    51004 avail Mem 

4行目がメモリに関する記載です。見やすく整理すると、

Total980,012KiB
free64,996KiB
used799,364KiB
buff/cache115,652KiB

たしかにfreeが少ない。。
そして、Swapに関してはtotal 0のため、Swap領域を作ることでメモリ不足を解消できる可能性があります。

スワップ領域の作り方は下記記事を参考にさせて頂きました。

まず、スワップ用ファイルを作成します。
サイズは2GiBにします。

ターミナル(ssh接続)

$ sudo dd if=/dev/zero of=/Swapfile bs=1M count=2048
=> 2048+0 レコード入力
2048+0 レコード出力
2147483648 バイト (2.1 GB) コピーされました、 14.9788 秒、 143 MB/秒

続いて、

ターミナル(ssh接続)

$ ls /swap
=> No such file or directory

swapディレクトリがなく、ルート直下にSwapfileが生成されていたため、下記にて対応します。

ターミナル(ssh接続)

# swapディレクトリを作成
$ sudo mkdir swap

# Swapfileをswapディレクトリへ移動
sudo mv Swapfile swap

権限を変更します。※これをしておかないと、後々エラーがでます。

ターミナル(ssh接続)

#swapディレクトリへ移動
$ cd swap

#権限変更
$ sudo chmod 600 Swapfile

mkswapでスワップファイル用としてフォーマットします。

ターミナル(ssh接続)

$ sudo mkswap Swapfile
=> スワップ空間バージョン 1 を設定します。サイズ = 2 GiB (2147479552 バイト)
ラベルはありません, UUID=e0a25838-3c6d-4212-856c-cc1596216592

スワップファイルを有効化します。

ターミナル(ssh接続)

$ sudo swapon Swapfile

結果を確認してみます。

ターミナル(ssh接続)

$ top
top - 22:14:22 up 70 days,  6:14,  1 user,  load average: 0.02, 0.01, 0.00
Tasks: 212 total,   1 running, 171 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.3 ni, 99.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.3 st
KiB Mem :   980012 total,    60028 free,   819368 used,   100616 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.    38540 avail Mem 

5行目にSwapが追加されました。

ユニコーンを起動してみます。

ターミナル(ssh接続)

# ユニコーン起動
$ bundle exec unicorn_rails -c config/unicorn.conf.rb -E production -D
# 起動確認
$ ps -ef | grep unicorn | grep -v grep

無事起動確認できました。

同様のエラーがあれば、参考にしてもらえると嬉しいです。