EY-Office ブログ

nginxのproxy設定が案外たいへんだった

以前Apollo GraphQLに入門してみた記事を書きましたが、勉強は終わったのでReactアプリ用バックエンドを作りはじめました。

バックエンドにはいくつかの機能があり、nginxリバースプロキシを前段に入れる事にしました。nginxはリバースプロキシに良く使われているので設定ファイルは簡単に書けると思っていましたが、半日もかかってしまいました。😅

Nginx proxy

バックエンドの構成

今回のバックエンドは、Reactアプリ向けのサービスを提供する(GraphQL)APIサーバーと、ユーザーやデータの管理を行う管理画面Webアプリの2つの機能があります。データやユーザー管理情報等はPostgreSQLのデーターベースに格納しています。

そして、APIサーバー、管理画面は別のDocker Contenerで動きます。データーベースのPostgreSQLは開発環境ではDocker Contener、本番環境ではAmazon RDSを使い、コンテナーの構成管理はDocker Composeでおこなっています。

ただし当面は、管理画面Webアプリは作らずにデーターベースのメンテナンス用にpgAdminを使う事にしました。

初期の開発環境では上の図のようにAPI/管理画面は、別ポートでアクセスしていましたが、通信のSSL化やサーバーの設定等を考えると両方とも標準の80(HTTPS時は443)ポートで動かした方が良さそうです。そしてパス名の先頭で両サービスを分けられる用にnginxのリバースプロキシを入れる事にしました。

  • http://server/api/https://server/api へのアクセスなら http://localhost:5000 のAPIサーバーに接続
  • http://server/admin/https://server/admin へのアクセスなら http://localhost:5001 の管理画面Webアプリに接続

nginxのリバースプロキシ用設定

さてnginxの設定ファイルですが、APIサーバーはGraphQLなので固定URLへのシンプルなHTTP通信のみなので、ネット上の情報に良く書かれている

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /api/ {
      proxy_pass http://server:5000/graphql/;
    }

    location /pgadmin/ {
      proxy_pass http://pg_admin:5001/;
    }
}

で動きましたが、pgAdminは上手く行きませんでした。😞

pgAdminはWebアプリなので、別パスにあるCSSやJavaScript、画像なを配信する必要がありますし、ログインページにリダイレクトしたりします。

リダイレクト

pgAdminにアクセスすると、ログインページ /login?.....にリダイレクトしますが、ブラウザーには /admin/login?..... パスを送らないといけません。このへんはproxy_redirectで設定できるようですが、いろいろな記事を参考にしてみましたが上手くいきませんでした。

そんな時 Reverse Proxying to pgAdminという記事を見つけ、参考にしながら書いたところ動くようになりました。
しかし、よくよく見るとpgAminのドキュメントの下の方にも同じ設定が書かれていました。😅

80(443)以外のポート

しかし、開発環境では http://localhost:8080でnginxが動作するのですが、うまく8080ポートをアクセスしてくれません。

設定ファイルに、proxy_set_header Host $host; と書きホスト名をpgAdminに転送しますが、ポート番号は転送されないそうです、proxy_set_header Host $http_host; と書くとホスト名とポート番号が転送されるようになります。

最終的なnginxの設定ファイル

最終的なnginxの設定ファイルは、以下のようになりました。

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /api/ {
      proxy_pass http://server:5000/graphql/;
      proxy_set_header Host $http_host;
    }
    location /pgadmin/ {
      proxy_set_header X-Script-Name /pgadmin;
      proxy_set_header Host $http_host;
      proxy_pass http://pg_admin:5001/;
      proxy_redirect off;
    }
}

めでたしめでたし😊

- about -

EY-Office代表取締役
・プログラマー
吉田裕美の
開発者向けブログ