低スペックなマシンで npm ビルド時に OOM Killer が発生したらスワップファイルを設定する
Always Free な Linux IaaS 上で npm プロジェクトをビルドしようとしたら、エラーコード 137 が発生してしまった。コレは Out of Memory エラーのコードで、ビルドに必要なメモリが足りないということだ。
# エラーコード 137 でビルドが失敗している例
$ npm run build
> my-app@ build /home/neo/my-app
> ng build --prod
50% building 123/124 modules 1 active ...evkit/build-optimizer/src/build-optimizer/webpack-loader.js??ref--7-0!/home/neo/my-app/node_modules/rxjs/_esm2015/internal/operators/withLatestFrom.jsKilled
npm ERR! code ELIFECYCLE
npm ERR! errno 137
npm ERR! blog-editor@ buildc: `ng build --prod`
npm ERR! Exit status 137
npm ERR!
npm ERR! Failed at the blog-editor@ buildc script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/neo/.npm/_logs/2020-11-14T15_22_03_776Z-debug.log
Always Free な VM はメモリが 1GB 程度しかなく、ビルドに十分なメモリが確保できないようだ。
# メモリは 1GB 程度。Swap なるモノは 0B らしい
$ free -h
total used free shared buff/cache available
Mem: 975M 264M 590M 3.2M 121M 578M
Swap: 0B 0B 0B
そんな時どうするかというと、スワップ領域を作ってやれば良い。メモリに乗り切らないデータをファイルに退避できるように設定するワケだ。
# 2GB 分のスワップファイルを作る
$ fallocate -l 2G /swapfile
$ chmod 600 /swapfile
$ mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=77b227d5-b50e-49fb-8b0e-5ccfcef95a57
$ swapon /swapfile
$ echo '/swapfile none swap sw 0 0' >> /etc/fstab
$ echo 'vm.swappiness = 10' > /etc/sysctl.d/10-swappiness.conf
$ sysctl --load /etc/sysctl.d/10-swappiness.conf
vm.swappiness = 10
Ubuntu の VM では上のように実施できた。
# スワップ領域が 2GB 分増えている
$ free -h
total used free shared buff/cache available
Mem: 975M 263M 557M 3.2M 153M 566M
Swap: 2.0G 0B 2.0G
しかし、CentOS では fallocate
コマンドだと失敗するようで、元のスワップファイルの作り方を変えた。
# fallocate コマンドの代わりに以下で作る
$ dd if=/dev/zero of=/swapfile bs=1M count=2048
2048+0 レコード入力
2048+0 レコード出力
2147483648 バイト (2.1 GB) コピーされました、 2.46604 秒、 871 MB/秒
# 後のコマンドは先程と同じ
$ chmod 600 /swapfile
$ mkswap /swapfile
$ swapon /swapfile
$ echo '/swapfile none swap sw 0 0' >> /etc/fstab
$ echo 'vm.swappiness = 10' > /etc/sysctl.d/10-swappiness.conf
$ sysctl --load /etc/sysctl.d/10-swappiness.conf
このようにしたらスワップファイルが作れた。このあとビルドをやり直すと、多少時間はかかったが最後までエラーなくビルドが成功するようになった。
どうしてもメモリが増やせない VM で作業せざるを得ない時はこんなやり方で。