Node.jsアプリをUbuntu, Nginx環境で動かす

2020-08-29 | コメント(0)

Ubuntu 18.04 で Node.jsのWebアプリを Nginx で公開する方法。

UbuntuでNode環境を整えた時のミニマムな方法をエントリーとして残します。

以下ざっくり言うと、nodeの "http" を使用したシンプルなWebサーバーアプリをデーモン化して、Nginxのリバースプロキシで公開するまでの内容です。

後々、Express4 のアプリを nmp で実行する内容に更新したいと思っています。

そのまま apt install nodejs すると Version 8.x が入ってくるので、インストールする前に次のコマンドでリポジトリを更新しておきます。古いバージョンを特に必要としていなければ 12.x を使用します。

Node.js Version 12.x

curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -

Node.js Version 10.x を使用したい場合

curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -

リポジトリを更新したらNode.jsをインストールします。

sudo apt install nodejs -y

バージョンは node -v で確認できます。

node -v

# Version 12.x の場合
v12.18.3
# Version 10.x の場合
v10.22.0
# Version 8.x の場合
v8.10.0

Node 12.x (または 10.x) をインストールすると、NPMも同時にインストールされているはずです。

npm -v

6.14.6

Node.js 8.x の場合、NPMが入って来ないので、NPMをインストールしておきましょう。

sudo apt install npm -y

NPMが入ったらグローバルモジュールを更新しておきます。これは apt update の様に定期的に行っておくほうが良いです。
※NPMのグローバルモジュールとは、.NET Frameworkで言うところのGACのようなものです。通常はアプリ毎のnode_modulesフォルダでNPMモジュールが管理されますがグローバルに入れることで個々のアプリで明示しなくても参照可能なものになります。(詳細は後日追記したい)

sudo npm update -g npm

Node本体としてのインストールはここまでで準備完了です。

Nodeアプリでは、この他にNPMに関連するモジュール等で他の依存関係のものが必要になることが多いため、当エントリーの目的としては必要ではありませんが、node-gypのインストールとNPMグローバルへgulp-cliを入れるコマンドを記載しておきます。

node-gypのインストール

sudo apt install node-gyp -y

NPMグローバルにgulp-cliをインストール

sudo npm install -g gulp-cli

サンプルのためのWebアプリを準備します。
Visual Studio 2019のプロジェクトウイザードにはNode.jsのものが4種類あります。GitHub等にも色々とサンプルがありますが、シンプルなNodeを理解するためにも、ここはテキストベースで一から作成してみます。

まず、Webアプリとしてのルートフォルダを作成し、カレントを移動します。

sudo mkdir /var/www/nodejs/SampleWeb1
cd /var/www/nodejs/SampleWeb1

※ /var/www/ は Nginxをインストールすると作成されます。
※ /var/www/nodejs/ は nodejs用のアプリをここに纏めて配置しようと思って作成したものです。

SampleWeb1フォルダ内に、Nodeアプリ本体になるindex.jsを作成し、下記の内容を記述します。

sudo nano index.js
const http = require("http");
const port = 3000;

const server = http.createServer(function (req, res) {
    res.statusCode = 200;
    res.setHeader("Content-Type", "text/plain");
    res.end("Hello World");
});

server.listen(port);

Nodeの理解のために簡単にコードを説明すると、"http"を使用してWebサーバーを3000番ポートでリッスンするものです。
処理は単純で、HTTP要求に対して応答コード200、"text/plain"で"Hello World"を出力するものです。
本来は "text/html" としてHTML文を返すのが普通ですがサンプルのため簡略しています。

アプリが出来たので実行します。Node.jsの実行は node コマンドに実行するjsファイルを指定するだけで実行できます。

node index.js

この状態で、ブラウザで http://172.24.0.78:3000/ でサイトにアクセスすると Hello World が表示されます。このサンプルではブラウザ上の表示は1行の文字列が表示されるだけですが、HTTPヘッダーも正しく含まれた結果が表示されています。

nodeコマンドで実行するとターミナルが待機状態で固まった様になるので、CTRL + c で終了させます。

Node.jsのWebアプリがポート3000番で動かせることが確認できたら、Nginx側にリバースプロキシの設定をします。以下はNginxのデフォルトのサイト設定からの変更箇所です。52 - 59行目でポート3000番をNodeアプリに飛ばしています。
※冒頭のコメントは端折っています。

sudo nano /etc/nginx/sites-enabled/default
server {
        listen 80 default_server;
        listen [::]:80 default_server;
 
        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;
 
        root /var/www/html;
 
        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;
 
        #server_name _;
 
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
 
        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}
 
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
 
        location /sampleweb1/ {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection keep-alive;
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
}
...
...

location指定で /sampleweb1/ のリクエストをNodeアプリに向けていますが、ルートの location / (上の28行目箇所から)にリバースプロキシの設定をすれば、全てのリクエストをNodeアプリに向けることもできます。

保存したらNginxを再起動し、Nodeアプリも起動すれば、http://172.24.0.78/sampleweb1/ でNodeアプリの表示が確認出来ます。

sudo service nginx restart
node index.js

保存したらNginxを再起動し、Nodeアプリも起動すれば、http://172.24.0.78/sampleweb1/ でNodeアプリの表示が確認出来ます。

nodeコマンドでWebアプリの実行が出来ますが、毎度nodeコマンドを実行してられないのでデーモン化します。

Node.jsアプリのデーモン化は、forever や pm2 などがある様ですが、シンプルにsystemctlを使用した方法を記載します。

サンプルとして、デーモン用の設定ファイルは nodejs-sampleweb1.service としましょう。/etc/systemd/system/ の中に作成します。ファイルの内容は以下の通りです。

sudo nano /etc/systemd/system/nodejs-sampleweb1.service
[Unit]
Description=SampleWeb1 Node.js running
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/var/www/nodejs/SampleWeb1
ExecStart=/usr/bin/node /var/www/nodejs/SampleWeb1/index.js
KillMode=process
Restart=always
RestartSec=10
 
[Install]
WantedBy=multi-user.target

ファイルを保存したらsystemctlに登録します。

sudo systemctl enable nodejs-sampleweb1.service

systemctlに登録したら、起動しておきましょう。

起動

sudo systemctl start nodejs-sampleweb1.service

停止する場合は stop で停止します。

sudo systemctl stop nodejs-sampleweb1.service

デーモンの動きを確認する場合はUbuntuをリブートします。(リブートしても良い場合)リブート後もNodeアプリが動作していることが確認できます。

sudo reboot

ここまで、シンプルなNode.jsのサンプルアプリをnodeコマンドで実行させる方法とデーモン化の方法、Nginxのリバースプロキシ設定を記載しましたが、npmで実行するWebアプリとそのデーモン化までの方法を整理して、後に更新したいと思います。

カテゴリ:

コメントする

※HTMLタグは使えません

Author

あきちゃん

主に、.NETでWebシステムの設計と開発をしています。
(茨城県在住, 都内勤務)
プロフィール