やりたいこと
本番環境に近いweb環境を作って、実務の解像度を上げる。
今回はnginxとdockerで立ち上げたコンテナアプリケーションとの通信の方法で詰まったので記録します。
完成イメージ
ラズパイとクライアントの通信イメージ
コンテナの外でnginx動いています。
nginxの設定。nginxのlocationの書き方。
user pcmainte; nginx プロセスを実行するユーザー
worker_processes auto; nginx が使用するワーカープロセス数
error_log /var/log/nginx/error.log; エラーログの保存先ファイル
worker_connections 1024; 最大1024接続まで許可
赤色のhttp セクション
全部デフォルト設定のまま。
緑色のupstream・server セクション
リバースプロキシ先(バックエンドサーバー)を定義します。この場合、kajiApp という名前で、ローカルホスト(127.0.0.1)のポート5000で動作するアプリケーションを指定しています。
dockerで動いているアプリケーションのポートは5000番。
同じラズパイの中でnginxと、コンテナが動いているので127.0.0.1:5000
listen 80; このサーバーブロックがポート80(HTTPのデフォルトポート)でリクエストを待ち受けるよう指定。
server_name 100.64.16.104; このサーバーに対応するホスト名やIPアドレスを指定。100.64.16.104
黄色のlocationセクション
location / { ... } URLパスに基づく処理を定義します。この場合、クライアントからの100.64.16.104というリクエストに対する処理です。
proxy_pass http://kajiApp; リバースプロキシを指定します。この場合、upstream で定義した kajiApp にリクエストを転送します。
つまり、クライアントから100.64.16.104とリクエストされたら、kajiApp(127.0.0.1:5000)にリクエスト転送します。
proxy_set_header ... ロキシを通じてバックエンドに送信するリクエストヘッダーを設定
Host: クライアントのリクエストヘッダー Host をバックエンドに転送。
X-Real-IP: クライアントのIPアドレスをバックエンドに転送。
X-Forwarded-For: プロキシを通過したクライアントIPアドレスのリストをバックエンドに転送。
X-Forwarded-Proto: リクエストプロトコル(HTTP/HTTPS)をバックエンドに転送。
ここからlocation設定がうまくいかなかった備忘録を書きます。
html,css,javascriptごとにlocation設定しなければいけない設定
user pcmainte;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
upstream kajiApp {
server 127.0.0.1:5000;
}
server {
listen 80;
location /kajiApp/ {
proxy_pass http://kajiApp/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /kajiApp/static/style_Boost.css {
alias /home/pcmainte/project/kajiApp/flaskr/static/style_Boost.css;
try_files $uri =404;
}
location /kajiApp/static/favicon.ico {
alias /home/pcmainte/project/kajiApp/flaskr/static/favicon.ico;
try_files $uri =404;
}
location /kajiApp/static/modal.js {
alias /home/pcmainte/project/kajiApp/flaskr/static/modal.js;
try_files $uri =404;
}
location /kajiApp/static/script.js {
alias /home/pcmainte/project/kajiApp/flaskr/static/script.js;
try_files $uri =404;
}
location /kajiApp/static/sidebar.js {
alias /home/pcmainte/project/kajiApp/flaskr/static/sidebar.js;
try_files $uri =404;
}
location /kajiApp/static/chart.js {
alias /home/pcmainte/project/kajiApp/flaskr/static/chart.js;
try_files $uri =404;
}
location /kajiApp/static/ {
root /home/pcmainte/project/kajiApp/flaskr/static;
autoindex on;
try_files $uri $uri/ =404;
}
}
}
クライアントから
100.64.16.104/kajiApp/
というリクエストをもらったとき、nginxは127.0.0.1:5000にリクエストを転送する設定です。
絶対パスですべてのファイルを書いてあげないとページ遷移してくれませんでした。
なぜこのような書き方をしたかというと、
ひとつのアプリケーションを稼働させるとき、
クライアントからのURLリクエストは、
100.64.16.104/ これでいいかもしれませんが、
2つ以上のアプリケーションを稼働させるとき、
クライアントからのURLリクエストは、
100.64.16.104/kajiApp/
100.64.16.104/App2/
というようにわけてあげないとnginx側がどちらのアプリに接続させればいいかわからないと考えたからです。
ただこの様にすべての転送先をlocationファイルに書いていくのはアプリでページを増やしたときにnginx.confの設定も見直さなければいけないので、避けたいと考えます。
改善案
user pcmainte;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
upstream kajiApp {
server 127.0.0.1:5000;
}
server {
listen 80;
server_name kajiApp.example.com;
charset UTF-8;
location / {
proxy_pass http://kajiApp;
}
}
server {
listen 80;
server_name unko.com;
location / {
root /home/pcmainte/project/App2;
index index.html;
}
}
}
クライアント側の
C:\Windows\System32\drivers\etc\hosts というファイルに
「100.64.16.104 kajiapp.example.com」を追加します。
これを追加することで kajiapp.example.com = 100.64.16.104 とみなされます。
クライアントからkajiapp.example.comと接続してもらえばnginxは127.0.0.1:5000のアプリ画面を返します。
2つ目のアプリですが、仮にunko.com というものを作るとして、↑の設定だとするならば、クライアント側でhostsファイルに「100.64.16.104 unko.com」を追加したうえで、unko.comを検索すると、unko.comに繋がります。 サーバー側のファイルは、/home/pcmainte/project/App2/index.htmlです。
成功画面
更に改善案
ただ、この設定だとクライアント側にいちいち名前解決のため、「100.64.16.104 unko.com」を設定しなければいけないのは面倒なので、同一ネットワーク内の端末の名前解決を一括で行ってくれるDNSサーバ。もしくはドメインを取得したりするのかな?と考えます。
次はDNSサーバを作って、もっと楽ができないか試してみます。
今後
HTTPS通信とFWをラズパイサーバーに実装してより堅牢にする。
DNSサーバーで名前解決を楽にする。