Docker ComposeでNode-REDとnginxを動かしてみる

Raspberry Pi
Docker Composeを使ってNode-REDとnginx 2つのコンテナを動かしてみます。
nginxのリバースプロキシを使ってnginxの80番ポートをブラウザで開くとNode-REDの1880ポートへ転送されNode-REDのフローが表示できる事を確かめてみます。


前回の記事 Raspberry PiにDocker Composeをインストールする
まででDocker Composeをインストールできました。

今回はDocker Composeを使ってNode-REDを動かします。Node-REDだけでは面白くないので、nginxも動かしてみます。nginxのリバースプロキシ機能を使ってNode-REDを操作できるようにします。

Node-REDを動かす

いきなり2つのコンテナを動かすと何が何だかわからなくなりますので順番に話を進めてみます。まずはNode-REDだけをDocker Composeで動かしてみます。
Node-REDをDockerで動かす方法はNode-REDの公式HPに書いてあります。
Running under Docker | Node-RED
Docker HubにコンテナがありARM用イメージもあります。
node.jsのバージョンは8のようです。バージョン10のイメージもあるようですがRaspberry Pi用はこの記事公開時まだありません。
Note: there is currently no rpi-v10 available
Node-REDコンテナの動かし方を一通り眺めます。
Node-REDの設定ファイルとフローの保存ファイルをホスト側ディレクトリとリンクすれば良いようです。また、ポート1880を任意のポートで公開しています。
これを元にdocker-compose.ymlファイルを作ります。

まずはDocker用ファイルの置き場所を作りましょう。~/Docker以下にまとめる事にします。
mkdir ~/Docker
cd ~/Docker

docker-compose.ymlの準備

docker-compose.ymlファイルを作り編集します。
nano docker-compose.yml
コンテナで動くプログラムは他のコンテナやホストとは独立しています。ネットワークやディレクトリ構造も独立しています。docker-composeではコンテナをどうやって作るかやコンテナ間のネットワーク接続、ネットワークのホスト側への公開、ホスト側ディレクトリとのリンクなどを記述します。
ここにNode-REDコンテナを動かす命令を書いていきます。docker-compose.ymlに次のように書きました。
version: '3'
services:
  nodered1:
    image: nodered/node-red-docker:rpi
    volumes:
      - ./node-red1:/data
    environment:
      - FLOWS=my_flows.json
    restart: always
    ports:
      - 1880:1880
少し説明します。
version:というのはdocker-compose.ymlファイルの書かれた書式のバージョンを表すそうです。今は'3'となっています。古いDocker Composeでは'2'とか’1’だったそうです。ググった時はバージョンに気をつけましょう。version:を書かずに動かすとservicesなんて知らないよとエラーが出てしまいました。
services:に動かしたいコンテナを書いていきます。複数のコンテナを書いておけます。
nodered1:というのはある一つのコンテナの名前です。好きな名前を書けます。この下にコンテナの動かし方を書いていきます。
image:というのはコンテナのイメージを指定します。ここではDocker Hubの"nodered/node-red-docker:rpi"を使うと書いています。
volumes:というのはコンテナ内のディレクトリとホスト側のディレクトリを関連付けます。ここではコンテナ内の/dataディレクトリはホスト側の"./node-red1"ディレクトリにマウントされます。docker-compose.ymlファイルが置かれたディレクトリからの相対パスで書けます。
コンテナ内のディレクトリ構造はホストとは独立しています。コンテナ内のディレクトリとホストのディレクトリを関連付けてコンテナ内のプログラムの設定を変えやすくします。
environment:ではコンテナ内での環境変数を設定できます。今回はフローのファイル名を指定しました。
restart:ではコンテナが停止した時の動作を書けます。
ports:ではコンテナ内部のポート番号をホスト側へ公開する設定を書きます。

データ用ディレクトリの準備

docker-compose.ymlファイルのvolumeで”./nodered1”というディレクトリを使うと書いたので準備します。
mkdir nodered1
docker-compose.ymlファイルのあるディレクトリにnodered1というディレクトリを作りました。これから動かすNode-Redの設定ファイルやフローが保存されます。

Node-REDを動かす

Node-REDのコンテナを動かす準備ができました。動かしてみましょう。docker-compose.ymlファイルのあるディレクトリで
docker-compose up
と入れます。
正しくdocker-compose.ymlが書かれていればNode-REDのコンテナがDocker Hubからpullされるでしょう。Node-REDのイメージサイズは600MB弱あるので少し時間がかかるでしょう。
pullが終わればNode-REDコンテナが動きだします。イメージをpullするのは最初の一回だけです。次回からの起動は速くなります。
Node-REDの画面は
http://localhost:1880
で見られます。Raspberry PiのIPアドレスを指定してLANの他のPCからも見られるでしょう。

フローに何か書いてデプロイしてNode-REDのフローが動くことを確認しましょう。
docker-composeを動かしたターミナル画面でCtrl+Cを押すとコンテナが停止します。

"./nodered1"ディレクトリに設定ファイルなどが保存された事を確認します。フローのファイルは暗号化され見れなくなっているでしょう。

nginxを動かす

設定ファイルをホストディレクトリへコピーする

nginxは設定ファイルがいくつかあります。テスト時など頻繁に変更する設定ファイルをホスト側ディレクトリへコピーしておきます。一度nginxコンテナを動かしてコンテナからホストへ必要なファイルをコピーします。
docker-compose.ymlにnginxコンテナを動かす記述を追加します。
version: '3'
services:
  nodered1:
    image: nodered/node-red-docker:rpi
    volumes:
      - ./node-red1:/data
    environment:
      - FLOWS=my_flows.json
    restart: always
    ports:
      - 1880:1880

  nginx1:
    image: nginx
    ports:
      - 80:80
nginxのコンテナを作るため一度動かします。
docker-compose up
nginxが動いたか確認します。ターミナル画面に
Creating docker_nginx1_1   ... done
doneと出ていれば動いているでしょう。ブラウザからlocalhostを開くと"Welcome to nginx!"と表示されたページが見れるでしょう。もしも動かなければdocker-compose.ymlの書き間違えです。メッセージを確認しましょう。

”docker_nginx1_1”というのがnginxのコンテナの名前です。これを使ってnginxの設定ファイルをコピーしてホスト側ディレクトリに保存します。
Ctrl+Cを押してコンテナを停止してください。
コンテナの一覧を表示します。
docker-compose ps
Name                     Command                State     Ports
---------------------------------------------------------------------
docker_nginx1_1     nginx -g daemon off;             Exit 0          
docker_nodered1_1   /usr/bin/entry.sh npm star ...   Exit 165        
”docker_nginx1_1”がありますね。
このコンテナの中の
/etc/nginx/nginx.confファイル
/etc/nginx/conf.dディレクトリ
/usr/share/nginx/htmlディレクトリ
をホストへコピーします。
コピーするファイルの置き場所を作ります。docker-compose.ymlファイルのあるディレクトリ下にnginx1ディレクトリを作ります。
mkdir nginx1
docker cp docker_nginx1_1:/etc/nginx/nginx.conf ./nginx1/nginx.conf
docker cp docker_nginx1_1:/etc/nginx/conf.d ./nginx1/conf.d
docker cp docker_nginx1_1:/usr/share/nginx/html ./nginx1/html
これでコンテナ内のファイルがホストにコピーできました。
nginxの使い方によってはこれでは足りないかもしれません。今回の手順を参考に必要なファイルを使えるようにしてください。

ホストディレクトリの設定ファイルを使ってnginxコンテナを動かす

docker-compose.ymlファイルを編集してホストディレクトリの設定ファイルを使ってコンテナが動くようにします。
version: '3'
services:
  nodered1:
    image: nodered/node-red-docker:rpi
    volumes:
      - ./node-red1:/data
    environment:
      - FLOWS=my_flows.json
    restart: always
    ports:
      - 1880:1880

  nginx1:
    image: nginx
    volumes:
      - ./nginx1/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx1/conf.d:/etc/nginx/conf.d
      - ./nginx1/html:/usr/share/nginx/html
    ports: 
      - 80:80
これで動かすとホストのファイルを使って動くようになります。試しに./nginx1/html/index.htmlを編集してページの表示が変わるか見ると良いでしょう。

nginxのリバースプロキシを使ってNode-REDを使う

今までの設定でNode-REDとnginx 2つのコンテナが動くようになりました。次にnginxのリバースプロキシ機能を使ってNode-REDを表示させる設定をしてみます。
nginxにリバースプロキシの設定ファイルを追加します。設定ファイルはホストの"./nginx1/conf.d"ディレクトリに"proxy.conf"というファイルにします。ファイル名は".conf"で終わればお好みで付けられます。
"docker-compose.yml"ファイルがあるディレクトリを基準に説明します。
"proxy.conf"ファイルを編集します。
nano ./nginx1/conf.d/proxy.conf
今回は次のようにしました。
upstream nodered {
  server raspberrypi:1880 weight=1;
}

server {
  listen 80;
  server_name localhost;

  location /nodered/ {
    proxy_pass http://nodered/;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
  }
}
黄色で表示している"raspberrypi"というホスト名にしないと何故か動きません。ここを"localhost"、”127.0.0.1”あるいは"127.0.1.1"にしていると"502 Bad Gateway"エラーとなってしまいます。調べているのですがはっきりとした理由はわかりませんでした。

また、静的htmlの表示設定とかぶり、このままではうまく表示できません。静的htmlのポート番号を8080へ変更してしまいます。”./nginx1/conf.d/default.conf”ファイルを編集します。
nano ./nginx1/conf.d/default.conf
2行目の
listen       80;

listen       8080;
に変更して保存します。
静的htmlと共存するにはproxy.confのserverディレクティブに書いた内容をdefault.confのserverディレクティブ内へ書けば良さそうです。今回はやりません。

以上を設定後ブラウザで
"http://raspberry piのIPアドレス/nodered/"
を開くとNode-REDのフローエディタが表示されるでしょう。Node-REDの1880番ポートの代わりにnginxの80番ポートでNode-REDが表示されています。

まとめ

今回はDocker Composeを使って2つのコンテナを動かしました。
nginxのリバースプロキシを使いNode-REDを表示する設定をしました。
複数のコンテナをまとめて管理しネットワークを使う基本的な設定を学習できるでしょう。

今回はNode-REDのフローエディタを表示していますがこのような使い方をする事はまず無いでしょう。実際はフローで作ったAPIなどを公開する時にnginxのリバースプロキシを使います。
nginxには負荷分散の機能もあるのでAPIを複数のRaspberry Piで動かしAPIへのリクエストを適時分配することもできるそうです。クラスターコンピュータを作る基礎になります。

インターネットへ公開するにはnginxにSSLの設定をしたり、まだまだやることがありますが、あとは他のサイト様にお任せです。Dockerでコンテナの設定ファイルをどこに置いたらよいかなど理解すれば難しいことは無いでしょう。

"localhost"、”127.0.0.1”あるいは"127.0.1.1"を使うと502 Bad Gatewayが出てしまう理由がわかりません。Node-REDへのアクセスが拒否されてしまうのです。

今回までいじるとDockerの便利さが解ってくるのではないでしょうか。Node-REDとnginxを動かすようにしましたがRaspberry Piのシステム自体は何もいじっていません。Dockerコンテナをいじるだけで複雑な環境を一瞬で作ったり消したりできます。自分で作ったコンテナをイメージ化すれば他のRaspberry Piへ簡単に移動もできます。

コメント

最近のコメント

Threaded Recent Comments will be here.