🍉
nginx × docker でフロントエンドとバックエンドの振り分けをしました!(リバースプロキシ)
環境
- フロントエンド: nuxt
- バックエンド: rails
- Docker Desktop for Mac
やりたいこと
-
http://localhost/
でフロントエンドにもバックエンドにもアクセスする -
パスによってフロントエンドとバックエンドへの振り分けをしたい
- /api -> バックエンドへ
- それ以外 -> フロントエンドへ
-
現状
- バックエンド: railsが動いているcompose.yaml
services: rails: build: . command: bundle exec puma volumes: - .:/app ports: - 3000:3000 tty: true
- フロントエンド: nuxtが動いているcompose.yaml
services: nuxt: build: . volumes: - .:/app ports: - 3030:3000 command: npm run dev tty: true
- バックエンド: railsが動いている
nginxの役割
nginx ("engine x") is an HTTP web server, reverse proxy, content cache, load balancer, TCP/UDP proxy server, and mail proxy server.
引用: https://nginx.org/en/
-
webサーバーであり、リバースプロキシであり、キャッシュもできて、ロードバランサーにもなり、TCP/UDP proxy serverやmail proxy serverにもなる優れもののようです。
-
今回はリバースプロキシとして利用します。
リバース プロキシとは、外部ネットワーク(インターネット)からの接続を受け、何らかの処理を行った上で内部のサーバーに引き渡す、中継機能を果たす機器のことです
引用: https://www.f5.com/ja_jp/glossary/reverse-proxy#:~:text=リバース プロキシとは、外部,のようにふるまいます。こんな感じ↓↓
nginxのイメージ
- nginxのdockerの公式イメージがあったので、それを利用します
- https://hub.docker.com/_/nginx
- 独自の設定ファイルを作って、渡せば良さそうです
nginxの設定
- 設定ファイル:
/etc/nginx/nginx.conf
- 各directiveについては、公式docを参照
- プロキシ設定については、nginxでロードバランシング&リバースプロキシの設定の記事を参照しました
- TODO: 設定ファイルも詰まった部分があったので、また別でまとめておきたい
nginx.conf# 必須っぽいので入れました events { # イベント処理に関する設定 worker_connections 1024; # 最大同時接続数 } http { # upstream: プロキシ先の定義 # backendコンテナへ upstream backend { server rails:3000; }asd # frontendコンテナへ upstream frontend { server nuxt:3000; } # server: サーバー設定 server { # listenするポート番号 listen 80; # サーバー名 server_name localhost; # リバースプロキシ関連の設定 ## location: リクエストのパスによって振り分ける ## /api/ へのリクエストはbackendへ location /api/ { # `http://backend`でアクセスするとrails側でホスト名関連のエラーになったので、`localhost`を渡してあげます proxy_set_header Host $http_host; proxy_pass http://backend; } # その他へのリクエストはfrontendへ location / { proxy_pass http://frontend; } } }
docker composeにnginxを追加
-
nginxのサービスを追加します
- 作成した設定ファイルをコンテナ内にマウントするようにします
- バックエンド/フロントエンドへのアクセスはnginxを経由するので、rails/nuxtサービスのポートマッピングは削除します。代わりにnginxで80番ポートでアクセスできるように設定します
compose.yamlservices: rails: build: . command: bundle exec puma volumes: - .:/app tty: true # nginxのサービス追加↓ nginx: image: nginx:1.13 volumes: # 設定ファイルのマウント - ./nginx/nginx.conf:/etc/nginx/nginx.conf # 起動時のコマンド command: nginx -g 'daemon off;' ports: # localhostでアクセスするためにポートをマッピングします - 80:80 # nginxがbackend/frontendを参照するため、先にrailsコンテナが起動する必要がある # フロントエンドは別compose.yamlなので、先に立ち上げておく必要がある(ちょっとめんどくさいから微妙かも、、、) depends_on: - rails
-
networkの追加
- nginxとバックエンドとフロントエンドそれぞれのコンテナが同じネットワーク内に入れるようにします
compose.yaml# バックエンド/フロントエンドそれぞれのcompose.yamlに追加しました networks: default: name: my_network
-
最終的なcompose.yaml
- バックエンドcompose.yaml
services: rails: ...略... nginx: image: nginx:1.13 volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf ports: - 80:80 command: nginx -g 'daemon off;' depends_on: - rails networks: default: name: my_network
- フロントエンドcompose.yaml
services: nuxt: build: . volumes: - .:/app command: npm run dev tty: true networks: default: name: my_network
- バックエンド
動作確認
-
フロントエンド -> バックエンドの順に、
docker compose up -d
でコンテナを起動します- 起動順が決まっているのが面倒なので、なんとかしたい。。
-
localhost
にアクセスした時- nuxtにアクセスできました
- nuxtにアクセスできました
-
localhost/api
にアクセスした時- railsにアクセスできました
- routeを作成していないので、エラーは出ています。これからAPIを作成すればOK
Discussion