どうも、@ryusei__46です。
今回は、Next.jsで作ったWebアプリをVPSなどにセルフホストする際に、複数のNext.js製アプリをポート番号で分けて、リバースプロキシでアクセスがあったドメインごとに振り分ける方法を解説します。
公開したいWebアプリが1つしかない場合は問題ありませんが、HTTP通信で使用する80番ポートや443ポートを占有してしまうので、他のサービスで使用したかった場合に困ることになりますよね。
アプリごとにサーバーを用意するのは、リソースの無駄ですし、現実的ではありません。
個人開発や小規模事業をでは、できるだけランニングコストを抑えながら運用していきたいというのが本音だと思います。
もちろん、サービスが人気になってきてサーバーのリソースが足りなくなってきた場合は話は別です。
この記事を読むことで以下のことが分かります。
- リバースプロキシの設定方法
- Next.jsのインスタンスを必要なアプリの数だけ起動する方法
- Next.js製アプリをポート番号ごとに振り分ける方法
サーバー環境
- OS: Ubuntu 22.04(Windows 11 Pro WSL2)
- Node.js ver 20.51
- Next.js ver 14.0.2
- Open Lite Speed ver 1.7.10(リバースプロキシとして使用)
リバースプロキシの設定方法
今回リバースプロキシとして「Open Lite Speed」を使用します。
「Open Lite Speed」は、近年Nginxに対抗してシェアを伸ばしてきているオープンソースのWebサーバーソフトウェアになります。高速に動作し、WordPressやPHPプログラムなどを運用するのに使用されていますが、プロキシサーバーの機能も搭載されているため、内部へのリバースプロキシとして使用できます。
また、リバースプロキシとして使用したいだけならNginxでも良いのですが、Open Lite SpeedはGUIで操作できるWebの管理パネルを搭載しているため、設定がスムーズに行える利点があります。
今回はOpen Lite Speedを使用します。
Open Lite Speedと必要パッケージのインストール
まず、サーバーにリモートログインして、下記のコマンドでリポジトリーを追加します。
$ sudo wget -O - http://rpms.litespeedtech.com/debian/enable_lst_debian_repo.sh | sudo bash
リポジトリーが追加できたら、Open Lite Speedをインストールします。
$ sudo apt-get install -y openlitespeed
インストールが完了したら、一応以下のコマンドを実行してサービスが起動しているか確認しておきます。
$ systemctl status lsws
● lshttpd.service - OpenLiteSpeed HTTP Server
Loaded: loaded (/etc/systemd/system/lshttpd.service; enabled; vendor preset: enabled)
// activeになっていればOK
Active: active (running) since Tue 2023-10-31 06:26:54 JST; 2 weeks 3 days ago
Main PID: 942843 (litespeed)
CGroup: /system.slice/lshttpd.service
├─941746 lsphp "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
├─942843 "openlitespeed (lshttpd - main)"
├─942844 "openlitespeed (lscgid)"
├─942853 "openlitespeed (lshttpd - #01)"
├─942854 "openlitespeed (lshttpd - #02)"
├─950419 lsphp "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
├─950420 lsphp "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
└─950590 lsphp "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
次に管理者ユーザーの初期設定を行うために、以下の場所にあるシェルスクリプトを実行してください。
$ sudo /usr/local/lsws/admin/misc/admpass.sh
次に、Open Lite Speedに必要な専用のPHPパッケージもインストールしておきます。
$ sudo apt-get install lsphp82 lsphp82-common lsphp82-curl lsphp82-mysql lsphp82-opcache lsphp82-imap lsphp82-opcache
// シンボリックリンクを作成
$ sudo ln -sf /usr/local/lsws/lsphp82/bin/lsphp /usr/local/lsws/fcgi-bin/lsphp5
これが終わったら、ブラウザーでhttp://localhost:7080
にアクセスします。
そうするとログイン画面が表示されるので、先ほど初期設定した管理者ユーザーでログインします。
Open Lite Speedでリバースプロキシ設定をする
画面左のメニューから「バーチャルホスト」を押下し、「バーチャルホストリスト」と書かれた見出しの右にある「+」ボタンを押下します。
次の画面で、各種設定項目を入力します。主に以下の項目だけでOKです。
- バーチャルホスト名:自分が管理するのに分かりやすい名前を設定
- Virtual Host Root :Next.jsアプリのプロジェクトルートまでの絶対パス
- 設定ファイル:
$SERVER_ROOT/conf/vhosts/$VH_NAME/vhconf.conf
(基本的にはこれでOK) - シンボリックリンクを許可する:はい
- スクリプト/外部アプリを有効にする :はい
- 抑制された:はい
- 外部アプリのUIDモードの設定:Server UID
設定を追加できたら、バーチャルホストリストから追加したバーチャルホスト名をクリックし、詳細画面を表示します。
「一般」タブを選択し、赤枠で囲った部分
- Document Root:
$VH_ROOT/public
(全てのアクセスをNext.jsへプロキシするため、ここの設定は適当でも問題ないです。) - GZIP圧縮を有効にする:はい
に設定します。
次は、「外部アプリ」のタブで設定を行います。
「タイプ」で「Webサーバー」を選択して進みます。次のページで、
- 名前:一位の好きな名前を英数字で設定
- アドレス:実際にNext.jsを動かすポートを、ローカルループバックIPアドレスと共に指定します。(例:
http://127.0.0.1:8624
) - 最大接続数:500
- キープアライブタイムアウト:10
- 初期リクエストタイムアウト(秒:15
- リトライタイムアウト(秒):10
- 応答バッファリング:はい
を設定して外部アプリを追加します。
次に、「コンテキスト」タブで設定を行います。「+」ボタンでコンテキストの設定追加ページを表示し、「タイプ」で、「Proxy」を選択して進みます。次のページで、
- URI:
/
(ルートパスを設定し、ドメインに来た全てのアクセスを外部アプリに設定したポート番号に転送します) - Webサーバー:先ほど設定した外部アプリを選択
を設定して保存します。
次に、HTTPリスナーの設定を追加します。画面右のメニューより、「リスナー」をクリックし、「+」ボタンより設定を追加します。
- リスナー名:一位の分かりやすい名前を設定する
- IPアドレス:「ANY IPv4」を選択
- ポート:80
これで設定を保存すると、標準的な80番ポートで待ち受けるHTTPリスナーが起動するようになります。
最後に、ドメインの設定を行います。
今しがた追加したHTTPリスナーをリスナーリストから選択し、「バーチャルホストマップ」の見出しの右端にある「+」ボタンをクリックし、アプリに割り当てたいドメインを設定できます。
- バーチャルホストマップ:上記で追加したバーチャルホストをプルダウンメニューから選択
- ドメイン:割り当てたいドメインを設定(例:blog.localhostやexample.comなど)
設定が終了したら、最後に画面右上の「再起動」ボタンをクリックして、今までの設定を反映させます。
動かしたいNext.jsアプリの数だけ上記の設定を行うことになります。
Open Lite Speedの開設はこれで終了です。
必要な数だけNext.jsのサーバーを起動させる
では、今回はscreen
コマンドを使って、複数のNext.jsのインスタンスを管理していきたいと思います。
といっても操作は簡単です。Linuxであれば標準搭載されているので別途インストールする必要はありません。まず、ターミナルでscreen
と打ち込みエンターキーを押します。
そうすると、新しいターミナルセッションが開始されるので、cd
コマンドでNext.jsのプロジェクトディレクトリーに移動し、Open Lite Speedのバーチャルホストの外部アプリに設定したポート番号で、Next.jsのサーバーを起動します。
問題なく起動したら、キーボードのCtrl + A・D
でセッションから離脱(でタッチ)します。再度再接続したい場合は、screen -ls
コマンドで現在起動しているターミナルセッションを一覧表示し、項目のそれぞれ先頭に表示されているスクリーンID(数値)を確認し、screen -r [screen ID]
で再接続(アタッチ)できます。
ちなみに、セッション内で画面をスクロールしたい場合は、キーボードのCtrl + A・[
でコピーモードに切り替えれば上下矢印キーでスクリーンに出力されているログをスクロールしながら確認できるようになります。
screen
コマンドの詳しい使い方が知りたい方は以下のQiitaの記事が参考になります。
以上で解説は終了です。こちらも起動させたい数だけターミナルセッションを作成していきます。
本当は、PM2というNode.jsのインスタンスを管理するオープンソースのツールがありますが、まだ導入できていないので、余裕ができたらキャッチアップして記事にまとめたいと思います。
一応PM2の公式サイトを載せておきます。
おわりに
やはり、Next.jsはVercelにデプロイして運用していることが多く、セルフホストする場合の知見が探しても乏しいようでした。私は以前から、PHPやらWordPressを扱ってきた身だったので、Open Lite Speedは使い慣れていました。Nginxも軽量で良いのですがやはりWebのGUIが使えるのは分かりやすくて良いと思います。
この方法で、Next.jsのサーバーを同じマシンで膨大な量管理できるようになりますし、PHPも使える(Open Lite speedはこっちが本命)ので、同時にWordPressやらPHPのシステムも運用できます。さらに言えば、リバースプロキシとして使えるということは、RubyやPythonなど様々な言語でサーバーを立てたとしても全て同一マシン上で動作させることが可能です。
これは結構革新的だと個人的には感じました。
以上です。この記事の内容を実践してトラブルや間違っていることなどあれば、コメントやお問い合わせ、またXのダイレクトメッセージで連絡してみてください。