#今回やりたかったこと
Next.js、APIサーバー、PostgresSQLなどの勉強のためにちょっとしたウェブアプリを作りたいと思ってました。
ただお金かけたくないので、サーバー、データーベース、画像など全部丸々VPSに置くことにしました。
色々VPS調べてたところ、Vultrが東京リージョンあり、そしてメモリ1GB環境が月5ドルで使えたので、Vultrで決めました。
また、Node.jsだと海外VPSの方が公式ドキュメントが多い印象(日本のサービスあまり調べてないだけかもしれません)だったので、そういう意味でも海外サービスの方がやりやすそうな雰囲気です。
最終的な環境としては以下の様な感じです。
- VPS 1024 MB RAM, 32 GB SSD, Ubuntu 20.10 x64
- Node.js 14.15.4
- Next.js 10.0.3
- Typescript 4.1.3
- PostgresSQL 12.5
##VultrのUbuntu環境でNode立ち上げ
Digital Oceanを利用していますが、Next.jsアプリをUbuntuでデプロイする超詳細な記事があったので、ありがたく参考にさせていただきました。記事通りなので、詳細は割愛します。
参考:How to Deploy a Next.js Website to a DigitalOcean Server
##VultrとGoogle Domainsでドメイン設定
最初ドメインの設定をする際に、一部設定が足りておらず、DNS_PROBE_FINISHED_NXDOMAINのエラーがちょくちょく出ていました。
幸いにもセットアップ方法を書いてくださってる方がいたので、無事修正できました。記事通りなので、詳細は割愛します。
参考:Vultr DNS Setup with Google Domains
##Next.jsのビルドがサーバーで失敗する
VPS側のセットアップが諸々完了したものの、肝心のビルドが中々上手くいきませんでした。
ローカルでは問題なかったのですが、サーバー側で失敗してしまう原因が今回2つありました。
- ローカルファイルとGitで大文字小文字がずれている
- サーバーのメモリ不足
###ローカルで大文字から小文字に変更した際に、Gitに反映されていなかった
今回初めて知ったのですが、フォルダ名を大文字から小文字に変えた際に、Gitに勝手に反映される訳ではないみたいです。(ローカル環境がケースインセンシティブ?)
例:
ローカル: Elements => elements
Git: Elements => Elements
そのため、サーバーでpullした際にディレクトリは大文字の状態で、import文が小文字でレファレンスするようになってしまい、エラーになりました。
###貧乏人サーバーではビルドにメモリが足りない
こっちが中々面倒でした。VPSはメモリ1GBのものだったのですが、それが原因でビルド時にnodeがメモリ不足になってしまいました。
TypeScriptのエラーや無限ループによるエラーなどもあり得ますが、今回はローカルでビルドできていたので、確実にメモリ不足でした。以下の対応で無事ビルドできました。
- ubuntuのスワップ領域追加
- nodeの--max-old-space-sizeオプション追加
####ubuntuのメモリスワップ
Nodeのメモリ不足で色々調べていたら、スワップ領域の追加という対応が出てきたので、記事を参考に領域を追加しました。記事通りなので、詳細は割愛します。
参考:How To Add Swap Space on Ubuntu 20.04
参考:`npm install` が殺される on 低容量メモリ環境
###--max-old-space-sizeの設定
V8エンジンのデフォルトヒープ領域とやらを超えてしまうのを防ぐために、NODE_OPTIONSで--max-old-space-sizeを設定してあげます。
ちなみにデフォルト値を確認したところ、以下のように出ました。
node -e "console.log(v8.getHeapStatistics())"
{
total_heap_size: 4730880,
total_heap_size_executable: 524288,
total_physical_size: 3870832,
total_available_size: 521532920,
used_heap_size: 2851792,
heap_size_limit: 525074432, ←これを変える。
malloced_memory: 8192,
peak_malloced_memory: 91744,
does_zap_garbage: 0,
number_of_native_contexts: 1,
number_of_detached_contexts: 0
}
stackoverflow先生によると、heap_size_limitが--max-old-space-sizeオプションで変えられるみたいです。
heap_size_limit: The absolute limit the heap cannot exceed (default limit or --max_old_space_size)
参考:nodejs v8.getHeapStatistics method
NODE_OPTIONSから設定し直すと、以下のようになりました。
参考:JavaScript heap out of memory が発生したときに試したこと
export NODE_OPTIONS="--max-old-space-size=1024"
node -e "console.log(v8.getHeapStatistics())"
{
total_heap_size: 4730880,
total_heap_size_executable: 524288,
total_physical_size: 3811624,
total_available_size: 1082782208,
used_heap_size: 2792560,
heap_size_limit: 1086324736,
malloced_memory: 8192,
peak_malloced_memory: 420416,
does_zap_garbage: 0,
number_of_native_contexts: 1,
number_of_detached_contexts: 0
}
これでビルドの準備は完了し、上手くいくようになりました。
##その他参考にさせていただいた記事