Node.jsのインストール
各ユーザにて。バージョンはフロントに合わせる。
git clone https://github.com/nodenv/nodenv.git ~/.nodenv
git clone git://github.com/nodenv/node-build.git ~/.nodenv/plugins/node-build
echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
nodenv install 10.15.3
nodenv local 10.15.3
node -v
yarnも必要ならば
curl -o- -L https://yarnpkg.com/install.sh | bash
source ~/.bashrc
プロジェクトのインストールと起動確認
git clone git@bitbucket.org:test/test.git repo/
yarn install
yarn run build
#フロントのコマンド設定による→nuxt buildのこと
yarn start
#フロントのコマンド設定による→nuxt startのこと
#localhost:3000で起動する
apacheの設定
Let's用にドキュメントルートも残しつつ、プロキシで3000ポートへ
<VirtualHost *:80>
ServerName example.com
ErrorLog /home/example/logs/error_log
CustomLog /home/example/logs/access_log common
<Proxy *>
Require all denied
Require ip xxx.xxx.xxx.xxx
</Proxy>
DocumentRoot /home/example/public_html
ProxyPass /.well-known/ !
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
yarn start
している状態で、httpへアクセスし、表示されるかどうか確認する。
PM2でデーモン化
yarn startで起動したプロセスは終了しておく。
npm install pm2 -g
#管理するコマンドを指定するファイルを作成
vi pm2.config.js
module.exports = {
apps : [
{
name: "nuxt",
script: "yarn start",
cwd : '/home/example/repo/'
}
]
}
#開始
#nodenvでやってる場合はパスを指定
/home/example/.nodenv/versions/10.15.3/bin/pm2 start pm2.config.js
#systemctlに登録
/home/example/.nodenv/versions/10.15.3/bin/pm2 startup
#ここでsudoしろと言われるので、sudoまたはrootになって実行する
root$ env PATH=$PATH:/home/example/.nodenv/versions/10.15.3/bin /home/example/.nodenv/versions/10.15.3/lib/node_modules/pm2/bin/pm2 startup systemd -u example --hp /home/example
#root終了
#pm2立ち上がり時に起動するプロセスを保存
/home/example/.nodenv/versions/10.15.3/bin/pm2 save
Nuxtの更新方法
CIなどでは下記を実行
cd repo
git checkout . && git fetch && git pull
yarn install
yarn run build
/home/example/.nodenv/versions/10.15.3/bin/pm2 restart nuxt
APIサーバの設定
テスト中などIP制限をする場合は、NuxtのサーバのIPも許可する必要がある。
SSRの場合はクライアントではなく、サーバからアクセスがある。
運用してみて判明したよろしくない現象
問題1:プロジェクト更新時(pm2 restart nuxt)にサーバが1分ほど503で落ちていた
- 原因1
- restart時にnodeが数秒落ちる
- 原因2
- apacheがproxyで http://localhost:3000/ へ流す際に、送信先が落ちているので、一定時間(デフォルトで60秒)送信を止めていた。
- apacheのエラーログで
ap_proxy_connect_backend disabling worker for (localhost) for 60s
と表示 -
ProxyPass / http://localhost:3000/ retry=0
でデフォルト60秒が0秒になる。実際にnodeが立ち上がるまでは1秒ちょっとのようなので、落ちている時間をその1秒ちょっとまで減らすことは可能。だが、なるべくダウンタイムはゼロにしたい。
- apacheのエラーログで
- apacheがproxyで http://localhost:3000/ へ流す際に、送信先が落ちているので、一定時間(デフォルトで60秒)送信を止めていた。
問題2:ビルド時(yarn run build)に現在使用している.nuxtフォルダの中身が一時的に削除される
その結果、jsファイルなど404が発生する。
ビルドがある程度進むと解消される(ビルドが遅いので30秒くらいは404が発生してしまう)。
上記を解決するために
- CPUが複数コア使用できる場合は、pm2のclusterモードを使用すればいいらしい。
- 今回のサーバは1コアだが、試しにclusterモードで動かしてみたらエラーが発生した。
- 予備プロセスをホットスタンバイさせ、プロジェクト更新時は一時的に切り替える。
- 今回はこちらを採用
設定
apacheのロードバランス機能を使用
ProxyPass / balancer://devcluster/ lbmethod=byrequests timeout=1 maxattempts=1
ProxyPassReverse / balancer://devcluster/
<Proxy balancer://devcluster>
BalancerMember http://localhost:3002 loadfactor=1 retry=10
BalancerMember http://localhost:3003 status=+H
ProxySet failonstatus=500,503
</Proxy>
# ProxyPass / balancer://devcluster/ の最後のスラッシュが無いとエラーになったので注意
Apache モジュール mod_proxy
https://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html
Apacheロードバランサで負荷分散。冗長化構成を開発環境でも。~負荷分散と冗長化の基礎を添えて~
https://www.ritolab.com/entry/128
apacheのmod_proxy_balancerを使ってロードバランサを試してみる
http://djangoapplab.com/22/
mod_proxy_balancer の振り分け挙動について調べたのと failonstatus を試してみた
https://inokara.hateblo.jp/entry/2013/12/04/071312
Apacheで実現するロードバランサー
https://www.geek.sc/archives/777
apache 2.2.12以降で ProxyPassReverse が balancer:// でも使えるようになってた
https://hogem.hatenablog.com/entry/20100908/1283951825
“No protocol handler valid for the URL” with httpd mod_proxy_balancer
https://serverfault.com/questions/773449/no-protocol-handler-valid-for-the-url-with-httpd-mod-proxy-balancer
ホットスタンバイ用のプロジェクトフォルダを作成
git clone -b develop git@bitbucket.org:test/test.git /home/dev_example/repo_hotstandby
yarn install
yarn run build
PM2でプロセスを2個起動
ポートを別々にする。
{
name: "dev_nuxt",
script: "yarn start",
cwd: "/home/dev_example/repo/",
env: {
PORT: 3002,
NODE_ENV: "development"
}
},
{
name: "dev_nuxt_hotstandby",
script: "yarn start",
cwd: "/home/dev_example/repo_hotstandby/",
env: {
PORT: 3003,
NODE_ENV: "development"
}
}
テスト
通常使用するプロセスをstopしてみる。
問題なくサイトが見えれば、ホットスタンバイしているプロセスが使用されているのが確認できる。
CI
- 通常プロセスをstop→ホットスタンバイプロセスが使用される
- 通常プロジェクトを更新
- 通常プロセスをstart
- sleep(確実に立ち上がるのを待つ)→通常プロセスが使用されるようになる
- ホットスタンバイプロジェクトを更新
- ホットスタンバイプロセスをrestart
cd /home/${DEV_PREF}example/repo
/home/${DEV_PREF}example/.nodenv/versions/10.15.3/bin/pm2 stop ${DEV_PREF}nuxt
git checkout . && git fetch && git pull
yarn install
yarn run build && /home/${DEV_PREF}example/.nodenv/versions/10.15.3/bin/pm2 start ${DEV_PREF}nuxt
sleep 10
cd /home/${DEV_PREF}example/repo_hotstandby
git checkout . && git fetch && git pull
yarn install
yarn run build && /home/${DEV_PREF}example/.nodenv/versions/10.15.3/bin/pm2 restart ${DEV_PREF}nuxt_hotstandby
ログの場所
/home/example/.pm2
pm2.log
# pm2をリスタートした場合などのログ
/home/example/.pm2/logs
# 各プロセスのログ。nodeのエラーなどもここに出る