
これをお届けするために血と汗と涙を流しました。デスバレーの灼熱の暑さに苦しみ、マッキンリー山の頂上を制覇しました。多くを犠牲にしました。
この投稿で共有されているコンテンツの多くは私のオリジナルの作品ではありません。可能な限り、オリジナルの作品にリンクバックしています。
この記事はLinuxを扱えることを前提としています。
本番環境でUbuntu上でNode.jsアプリケーションをホスティングし管理するための包括的なガイドを見つけることができませんでした。この主題に関する複数の記事をまとめました。この記事の終わりまでに、独自のUbuntuサーバーを設定し、継続的インテグレーションサーバー経由でNode.jsをデプロイできるようになることを願っています。
環境
私はWindows上のTeamCityを使用し、GitHubからAWS上でホストされているUbuntuにコードをデプロイしています。
技術
この記事では以下の技術を使用しました:
- AWS上のUbuntu 14.04
- Plink 0.64
- TeamCity 9.1
- GitHub
- Nginx 1.9.3
Ubuntuの設定
ここでは詳細には触れません。Amazon Web Services(AWS)を使えばかなり簡単にできます。どこにあるか、または独自のサーバー上にあるかは問題ではありません。
いくつかの落とし穴に遭遇しました。まず、ポート80が開いていることを確認してください。ポート80を閉じたまま接続しようとするという愚かな間違いを犯しました。自分の間違いに気づいたとき、サイの尻のような気分でした。
ソースからのNode.jsのインストール
Node.jsはGoogleのV8 JavaScriptエンジンを使用するサーバー技術です。2010年のリリース以来、広く人気を博しています。
以下の手順は元々Digital Oceanの投稿から来ています。
apt-getからNode.jsをインストールするオプションもありますが、数バージョン遅れることになります。最新版を入手するには、ソースからNode.jsをインストールします。
このセクションの終わりまでに、nodeの最新安定版(この記事執筆時点)をダウンロードし、ソースをビルドしてNode.jsをインストールします。
サーバーにログインします。パッケージリストの更新から始めましょう。
sudo apt-get update
すべてのパッケージをアップグレードすることも提案します。これはNode.jsには必要ありませんが、サーバーを最新の状態に保つのは良い習慣です。
sudo apt-get upgrade
サーバーは最新の状態になりました。ソースをダウンロードする時間です。
cd ~
執筆時点では12.7がNode.jsの最新安定版リリースです。最新バージョンについてはnodejs.orgをチェックしてください。
wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
ダウンロードしたアーカイブを展開します。
tar xvf node-v*
新しく作成されたディレクトリに移動します。
cd node-v*
Node.jsを設定してビルドします。
./configure
make
Node.jsをインストールします。
sudo make install
ダウンロードしたファイルと展開したファイルを削除するには。もちろん、これはオプションです。
cd ~
rm -rf node-v*
おめでとうございます!Node.jsがインストールされました!そしてそれほど難しくありませんでした。
Nginxの設定
Node.jsはWebサーバーとして機能できますが、世界に公開したいものではありません。産業用の、堅牢で機能豊富なWebサーバーがこのタスクにより適しています。このタスクにはNginxを選びました。
これは必要な機能を備えた成熟したWebサーバーです。Node.jsの複数のインスタンスを実行するには、ポートフォワーディングが必要です。
なぜ同時に複数のNode.jsインスタンスを実行する必要があるのか疑問に思うかもしれません。それは妥当な質問です…私のシナリオでは、1つのサーバーがあり、同じマシン上でDEV、QA、PRODを実行する必要があります。理想的ではないことは分かっていますが、各環境に3つのサーバーを立てたくありません。
まずはNginxをインストールしましょう。
sudo -s
add-apt-repository ppa:nginx/stable
apt-get update
apt-get install nginx
Nginxが正常にインストールされたら、ドメインを設定する必要があります。各サイトを独自のドメイン/サブドメインに配置したいと想定しています。そうでなく、異なるサブフォルダーを使用したい場合、それは実行可能で非常に簡単です。ここではそのシナリオはカバーしません。それを行う方法についてのドキュメントは豊富にあります。異なるドメインの設定と対応するNode.jsインスタンスへのポートフォワーディングについてのドキュメントはほとんどありません。これが私がカバーする内容です。
Nginxがインストールされたので、/etc/nginx/sites-available/
にyourdomain.comのファイルを作成します。
sudo nano /etc/nginx/sites-available/yourdomain.com
新しく作成したファイルに以下の設定を追加します。
# the IP(s) on which your node server is running. I chose port 9001.
upstream app_myapp1 {
server 127.0.0.1:9001;
keepalive 8;
}
# the nginx server instance
server {
listen 80;
server_name yourdomain.com;
access_log /var/log/nginx/yourdomain.log;
# pass the request to the node.js server with the correct headers
# and much more can be added, see nginx config options
location / {
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://app_myapp1;
}
}
「yourdomain.com」を実際のドメインに置き換えることを確認してください。エディターを保存して終了します。
sites-enabledディレクトリにこのファイルのシンボリックリンクを作成します。
cd /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com
すべてが正しく動作していることをテストするために、シンプルなnodeアプリを作成し、/var/www/yourdomain.com/app.js
に保存して実行します。
手元にない場合のシンプルなNode.jsアプリです。
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');}).listen(9001, "127.0.0.1");
console.log('Server running at http://127.0.0.1:9001/');
Nginxを再起動しましょう。
sudo /etc/init.d/nginx restart
まだ開始していない場合は、Node.jsインスタンスを開始することを忘れないでください。
cd /var/www/yourdomain/ && node app.js
すべてが正しく動作している場合、yourdomain.comにナビゲートすると「Hello World」が表示されます。
異なるNode.jsインスタンス用に別のドメインを追加するには、上記の手順を繰り返す必要があります。具体的には、新しいNginx設定ファイルでupstream名、ポート、ドメインを変更する必要があります。proxy_passアドレスはnginx設定ファイルのupstream名と一致する必要があります。upstream名とproxy_pass値を見れば、私の意味が分かるでしょう。
要約すると、ソースからNodeJSをインストールし、Nginxのインストールを完了しました。NginxとNode.jsでポートフォワーディングを設定してテストしました。
PM2のインストール
「PM2とは何か?」と疑問に思うかもしれません。私も最初に聞いたときはそう思いました。PM2はNode.jsアプリケーション用のプロセスマネージャーです。Node.jsにはあまり多くの機能が付属していません。これがその魅力の一部です。この欠点は、まあ、その前にレイヤーを提供する必要があることです。PM2はそれらのレイヤーの1つです。
PM2はNode.jsプロセスのライフサイクルを管理します。終了すると、PM2が再起動します。サーバーが再起動すると、PM2がすべてのNode.jsプロセスを再起動します。また、広範囲な開発ライフサイクルプロセスも持っています。PM2のこの側面はカバーしません。よく書かれたドキュメントを読むことをお勧めします。
ターミナルにログインしていると仮定して、NPM経由でPM2をインストールすることから始めます。NpmはNode.jsパッケージマネージャー(npm)です。Node.jsをインストールしたときにインストールされました。
sudo npm install pm2 -g
それだけです。PM2がインストールされました。
PM2の使用
PM2は使いやすいです。
PM2のhello worldはシンプルです。
pm2 start hello.js
これによりアプリケーションがPM2のプロセスリストに追加されます。このリストはアプリケーションが開始されるたびに出力されます。
この例では、2つのNode.jsアプリケーションが実行されています。1つはapi.dev、もう1つはapi.preと呼ばれています。
PM2は自動的にアプリの名前をリストの「App name」に割り当てます。
初期設定では、PM2はサーバーの再起動時に自動起動するように設定されていません。コマンドはLinuxのフレーバーによって異なります。私はUbuntu上で実行しているので、Ubuntuコマンドを実行します。
pm2 start ubuntu
まだ完了していません。PM2バイナリへのパスを追加する必要があります。幸い、前のコマンドの出力がその方法を教えてくれます。
出力:
[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
Run the command that was generated (similar to the highlighted output above) to set PM2 up to start on boot (use the command from your own output):
sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
その他のPM2使用例(オプション)
アプリ名でアプリケーションを停止
pm2 stop example
アプリ名で再起動
pm2 restart example
PM2で管理されている現在のアプリケーションのリスト
pm2 list
プロセス開始時に名前を指定。PM2を呼び出すと、JavaScriptファイルを名前として使用します。これがうまくいかない場合があります。名前を指定する方法は次のとおりです。
pm2 start www.js --name api.pre
これでPM2を始めるのに十分でしょう。PM2の機能についてもっと学ぶには、GitHub Repoを訪問してください。
Plinkの設定と使用
「ベッツィーの牛の名前でPlinkとは何か?」と思っているでしょう。少なくともそれが私の考えでした。まだ何を考えるべきかわかりません。こんなものは見たことがありません。
映画Wall-eを見たことがありますか?Wall-eがスポークを取り出します。最初にフォークと一緒に置こうとしますが、合わず、次にスプーンと一緒に置こうとしますが、合いません。それがPlinkです。Putty(SSH)とWindowsコマンドラインの間のクロスです。
Plinkは基本的に、Linux(おそらくUnix)シェルにログインしながら、Windowsコマンドライン経由でbashコマンドを実行できます。
Plinkをダウンロードすることから始めます。これは単なる実行可能ファイルです。C:/Program Files (x86)/Plink
に置くことをお勧めします。後で参照する必要があります。
AWSでUbuntuインスタンスを実行している場合、Putty用の証明書が既に設定されています(Puttyを使用していると仮定しています)。
そうでない場合は、AWSのUbuntu用の互換性のあるSSH証明書があることを確認する必要があります。
AWSを使用していない場合は、コマンドラインでユーザー名とパスワードを指定でき、SSH証明書について心配する必要はありません。
PlinkでUbuntuに接続するコマンドラインの例です。
"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk"
これは先走りかもしれませんが、UbuntuサーバーでSSHスクリプトを実行するには、Plinkコマンドの最後に完全なパスを追加します。
"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-dev-ui.sh
そして、親愛なる読者、それがPlinkです。
NODE_ENVの理解
NODE_ENV
はexpressjsによって人気になった環境変数です。nodeインスタンスを開始する前に、NODE_ENV
を環境に設定します。コード内で環境に基づいて特定のファイルを読み込むことができます。
NODE_ENVの設定
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD
環境変数はprocess.env.NODE_ENV
を使用してNode.jsインスタンス内で取得されます。
例
var environment = process.env.NODE_ENV
またはexpressjsで
app.get('env')
*注:app.get('env')
はデフォルトで「development」になります。
すべてをまとめる
Node.js
、PM2
、Nginx
、Plink
がインストールされ、うまくいけば動作しています。これらすべてのピースを継続的インテグレーションソリューションにまとめる必要があります。
/var/www/yourdomain.com
にGitHubリポジトリをクローンします。SSHはHTTPSよりも安全ですが、HTTPSを使用することをお勧めします。これは理想的ではないことは分かっていますが、Ubuntu上でPlinkをGitHubで動作させることができませんでした。詳細には触れませんが、PlinkとGitHub SSH証明書の形式が異なり、Plink経由でSSH経由でGitHubを呼び出すことはうまくいきませんでした。問題を解決できる場合は教えてください!
GitHub pullを手動操作なしで行うには、ユーザー名とパスワードがorigin urlの一部である必要があります。
origin urlの設定方法です。もちろん、適切な場所に自分の情報を代入する必要があります。
git remote set-url origin https://username:password@github.com/username/yourdomain.git
リポジトリをクローンします。
cd /var/www/yourdomain.com
git clone https://username:password@github.com/username/yourdomain.git .
このディレクトリが隠しファイルを含めて完全に空でない場合、Gitはこのディレクトリにリポジトリをクローンしないことに注意してください。
ディレクトリ内の隠しファイルを見つけるには、このコマンドを実行します。
ls -a
接着剤として、シェルスクリプトを使用しています。私のスクリプトのコピーです。
#!/bin/bash
echo "> Current PM2 Apps"
pm2 list
echo "> Stopping running API"
pm2 stop api.dev
echo "> Set Environment variable."
export NODE_ENV=DEV
echo "> Changing directory to dev.momentz.com."
cd /var/www/yourdomain.com
echo "> Listing the contents of the directory."
ls -a
echo "> Remove untracked directories in addition to untracked files."
git clean -f -d
echo "> Pull updates from Github."
git pull
echo "> Install npm updates."
sudo npm install
echo "> Transpile the ECMAScript 2015 code"
gulp babel
echo "> Restart the API"
pm2 start transpiled/www.js --name api.dev
echo "> List folder directories"
ls -a
echo "> All done."
このシェルスクリプトをTeamCityで起動していますが、何でも起動できます。
生のコマンドです。
"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-yourdomain.sh
exit
>&2
それだけです。
終わりに
このプロセスにはいくつかの粗い部分があります…時間をかけてそれらの部分を磨きたいと思います。提案がある場合は、コメントに残してください。
このドキュメントは私のGitHubリポジトリにあります。技術は変化するので、エラーを見つけた場合は更新してください。その後、この投稿を更新します。
著者:Chuck Conwayはソフトウェアエンジニアリングと生成AIを専門としています。ソーシャルメディアで彼とつながりましょう:X (@chuckconway) または YouTube をご覧ください。