前提・実現したいこと
dockerを用いて、1つのサーバ内で3つのコンテナを起動しています。
それぞれのコンテナはdocker-bridgeネットワークで接続されています。
・reactによるフロントエンド(コンテナ名:fe)
・apiサーバ1(コンテナ名:api1)
・apiサーバ2(コンテナ名:api2)
feのみportを公開しています。
feからapi1,api2へコンテナ名をホスト名としてリクエストを送りたいです。
例:axios.get('http://api1/users')
できていること
feコンテナからapi1コンテナへのリクエストは正しく送られています。
以下の方法で確認しました。
サーバ内で以下のコマンドを実行
$docker exec fe curl -X GET "http://api1/users"
発生している問題
ブラウザの操作で発生するリクエストが正しく処理されません。
chromeのコンソールで、以下のようなエラーが出ます。
エラー:GET http://api1/users net::ERR_NAME_NOT_RESOLVED
reactのリクエストは、サーバではなくブラウザから送られているようで、ホスト名解決ができていないようです。
試したこと1:ブラウザからリクエストを送れるようにする
以下のように、それぞれのapiサーバを公開すれば実現できます。
例:docker run -p 3001:3000
とし、xxx.com:3001/usersでリクエストする。
しかしこの手法だと、fe以外からのリクエストも受け付けてしまいます。
各apiサーバは外部に公開せず、内部ネットワークのみからアクセスできるようにしたいです。
試したこと2:package.json proxy
package.jsonに"proxy": "http://api1"
と設定することで
api1へのリクエストは以下のように送ることができました。
例:axios.get('/users')
しかし、この手法だと、api2へのリクエストを送ることができません。
調査したこと:http-proxy-middleware
このミドルウェアを用いると、複数のプロキシを設定できるようです。
以下のような実装になります。
const apiProxy = createProxyMiddleware('/api', { target: 'http://www.example.org' }); // \____/ \_____________________________/ // | | // context options
ただ、この手法だと、用いるcontextに対し設定を書かなければなりません。
contextが複数のサーバでかぶっている(api1/usersとapi2/usersを利用したい)場合、rewite用いたコーディングが必要になります。
実現したいことに対し、非常に面倒です。
質問
前提とした構成が正しくないのでしょうか。(特にapiサーバを外に出したくないあたり?)
リクエストをブラウザからではなく、feコンテナから送る方法があるのでしょうか。
または、解決できるその他の方法があるのでしょうか。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー