質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

Q&A

解決済

2回答

1345閲覧

aws上でrailsコンテナとreactコンテナの間でaxiosを利用して通信することは可能でしょうか

senseIY

総合スコア281

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

0グッド

0クリップ

投稿2022/08/30 09:11

前提

現在AWSを使用してバックエンド側とフロントエンド側に分けて開発したポートフォリオをデプロイしようとしています。デプロイはこちらの記事を参考にしました
。作業自体は終わってフロントエンド側の表示も上手く表示されているのですが、rails側のコンテナとaxiosを利用した通信を行うことができません。
参考にしたサイトの通りに作ったのでこのような構造になっています。EC2(webサーバ)の部分でdocker-compose upをしています。
イメージ説明
(注意事項)*Railsを本番環境で起動すると500エラーが出てしまうため、今回はdevelopment開発でデプロイする方針を取っています。(デバッグの時間がないため)

発生している問題・エラーメッセージ(ドメインは伏せさせていただきます。)

j

1xhr.js:220 GET https://(ドメイン):3001/api/v1/auth/sessions net::ERR_CONNECTION_REFUSED

Reactのaxios通信をする部分の一部

tsx

1export const FetchUser = (userId: any) => { 2 return axios.get(`https://(ドメイン):3001/api/v1/users/${userId}`) 3 .then(res => { 4 return res.data 5 }) 6 .catch((e) => console.error(e)) 7}

docker-compose.yml

yml

1version: "3" 2 3services: 4 # db: 5 # image: mysql:8.0 6 # environment: 7 # MYSQL_ROOT_PASSWORD: password 8 # command: --default-authentication-plugin=mysql_native_password 9 # volumes: 10 # - mysql-data:/var/lib/mysql 11 # - /tmp/dockerdir:/etc/mysql/conf.d/ 12 # ports: 13 # - "3306:3306" 14 # cap_add: 15 # - SYS_NICE 16 api: 17 build: 18 context: ./backend/ 19 dockerfile: Dockerfile 20 # command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000" 21 command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" 22 volumes: 23 - ./backend:/myapp 24 - ./backend/vendor/bundle:/myapp/vendor/bundle 25 environment: 26 TZ: Asia/Tokyo 27 RAILS_ENV: development 28 ports: 29 - "3001:3000" 30 # depends_on: 31 # - db 32 stdin_open: true 33 tty: true 34 env_file: 35 - .env 36 front: 37 build: 38 context: ./frontend/ 39 dockerfile: Dockerfile 40 volumes: 41 - ./frontend/app:/usr/src/app 42 command: sh -c "yarn && yarn start" 43 ports: 44 - "80:3000" 45 # - "4000:3000" 46 environment: 47 - WDS_SOCKET_PORT=0 48# volumes: 49# # mysql-data: 50

試したことや考察など

1 踏み台サーバからアクセスできるか

踏み台サーバから接続確認をしてみました

j

1[ec2-user@ip-(伏せさせていただきます。) ~]$ curl (伏せさせていただきます。):3001/api/v1/users 2[]

これは登録しているuserを全て返すというindexアクションです。そのため、[]が返って来るのは正常な動作です。ですが、なぜか実際のURLから試すとエラーが発生してしまいます。

2 セキュリティーグループの設定に3001を設定

設定したものの、エラーは変わらず。

3 同一ec2(webサーバ)に向けてaxiosを設定

もしかすると、そのアプリケーションが動いているec2のIPアドレスでないと反応しないのではないかと考えて、axiosの通信先を以下のように設定してみました

j

1baseURL: "https://(伏せさせていただきます。):3001/api/v1

ですが、同じようにエラーになってしまいます。

ロードバランサーのパブリックIPアドレス EC2(踏み台サーバ)のIPアドレスからアクセスできるか

1 EC2のグローバルIP(踏み台サーバのもの):3001
*EC2のwebサーバはプライベートIPアドレスしか持っていないのでチェックしませんでした。
こちらを検索バーに入れて検索してみましたが、

j

1このサイトにアクセスできません (一応伏せさせていただきます。)で接続が拒否されました。

となってしまいました。
2 ロードバランサーのグローバルIP:3001

j

1このサイトにアクセスできません(同上)で接続が拒否されました。 2

*一応フロントエンド側にはアクセスできました

このようにどちらもアクセスできませんでした。

考察など

・1のように踏み台サーバにssh接続してアクセスは可能だが、検索バーに「EC2のグローバルIP(踏み台サーバのもの):3001」このような形で入力して検索するとアクセスできないのはなぜか分からない
・もしかすると、何かAWS側での設定ミスがあるかもしれません(しかし、コンテナは両者正常に起動しているし、フロントエンド側にはドメインからアクセス可能)
・まず、そもそもこの構成でaxiosによるコンテナ間の通信は可能なのか
・参考にしたサイトではAPIを叩いていなかったので分かりませんが、APIとReactの通信もルーターに設定しないといけないのでしょうか?

・出せる情報が少なくてすみません。不備があれば追記いたします。なにかしらアドバイスがあればよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

この構成ではAPI通信が出来ないと判明したので、構成を変えようと思います。皆様ありがとうございました。

投稿2022/08/30 10:18

senseIY

総合スコア281

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu_1985

2022/08/30 10:21

回答に書かせていただいたのですが、構成に課題はあるものの別にできないわけではありません。
senseIY

2022/08/30 10:24

返信ありがとうございます。すみません。入れ違いになってしまったようです。頂いた回答をもとにもう少し粘ってみます。
senseIY

2022/08/30 11:27

> このドメインとはALBに設定したのでしょうか。 はい。 それであればALBで3001をListenしていなければエラーになります。 >今確認したところ、確かに3001をlistenしていませんでした。そこで設定を追加しましたが、どうやら上手く通信できていないみたいです。エラーも先ほどと同様の物が返ってきました。 > また、そもそも内部だけで済む通信をわざわざインターネットに出す必要もありません。 リクエストを送る先が間違っているかと思います。  例えば、会員登録をするとします。そのフォームに入力された情報はReactが持っていると思いますが、それを送信する際には 1 VPCの外を通る(この構成ならばALBを通らないといけない) 2 同じEC2(webサーバ)で動いているコンテナに直接送信できる のどちらか(元々1しか知らなかったですが、回答から考察するに2もあり得る?)だと思いますが、直接frontコンテナからrailsコンテナへ情報を送ることは可能なのでしょうか?ローカル環境で通信した際にはlocalhostを使ったと思いますが、localhostはコンテナへ直接通信をしているのでしょうか?APIテスターなどを使った場合は直接ではないと思いますが、私はローカル環境でlocalhostを使っているときも1(正確にはVPCではないが)のような感じで、コンテナ同士が直接通信しているとは思っていなかったです。 > そもそも同サーバー内でrailsのコンテナとフロントのコンテナを双方動かしているのであればlocalhostにさえアクセスできれば動くはず(※)なので、ALBとかEC2とかは無視してまずは自サーバーのみで動く状態にしてください。 ※それがあるべき構成かは一旦ここでは置いておきます。 すみません。よくわかりませんでした。localhostの部分をec2(webサーバ)のIPアドレスに置き換えれば動くということでしょうか? > 結局同サーバー内のコンテナ間で通信できれば良いのでサーバー1台構成とやることは変わりません。 本当に申し訳ございません。ある方からアドバイスを頂いたのですが、「コンテナ間通信ではなくaxiosはクライアントのブラウザ側のJSで通信しているのでこの構成では通信は不可能ではないか」というご指摘を受けました。yu_1985様のおっしゃる通りコンテナ間の通信は可能なのだと思われますが、私の場合axiosを使用しているのでコンテナ間の通信はあまり関係ありませんでした。誤解を与えてしまう質問の書き方をしてしまい申し訳ございませんでした。やはりこの構成では通信は不可能なのではないかというのが今の私の見解でございます。
yu_1985

2022/08/30 12:12

>今確認したところ、確かに3001をlistenしていませんでした。そこで設定を追加しましたが、どうやら上手く通信できていないみたいです。エラーも先ほどと同様の物が返ってきました。 その後書いたのですが、そもそもやるべきはALBで3001をListenすることではありません。 > 1 VPCの外を通る(この構成ならばALBを通らないといけない) そんなことはありません。EC2インスタンスのプライベートIPを取得できればいいわけですし、そもそもlocalhostに通信すればサーバ内に閉じた通信になります。 同一サーバー内でrailsもfrontも動かしているのだからこの構成ならそれで十分です。 > localhostはコンテナへ直接通信をしているのでしょうか ここで言う直接の定義がわかりませんが、localhost宛に通信をするのならローカルネットワーク内での閉じた通信になります。 > 私はローカル環境でlocalhostを使っているときも1(正確にはVPCではないが)のような感じで、コンテナ同士が直接通信しているとは思っていなかったです。 では、どのように通信していたのでしょう?わざわざどこかを介して通信していましたか? > すみません。よくわかりませんでした。localhostの部分をec2(webサーバ)のIPアドレスに置き換えれば動くということでしょうか? localhostで十分だと思います。サーバーの外に何があるかは一旦無視していいです。 > 本当に申し訳ございません。ある方からアドバイスを頂いたのですが、「コンテナ間通信ではなくaxiosはクライアントのブラウザ側のJSで通信しているのでこの構成では通信は不可能ではないか」というご指摘を受けました。 質問に書いてなかったのですが、frontのコンテナはSSRではなくて単にクライアントにJSを渡すだけなんでしょうか。 それであればクライアントからの通信なのでおっしゃるとおりこの構成自体が頓挫します。 そうではなく一旦frontのコンテナでリクエストを受け付けて、それをrailsのコンテナに流すのであれば自分の言ったことが実現できるかと思います(自分はこちらをイメージしていた)。 axios自体は単なるJS製HTTPクライアントなので、それだけではどこで動いてるかはちょっと判断つかないです。 アプリがどのような構成になっているのかまずは自分で確認してみてください。
senseIY

2022/08/30 12:22

> 質問に書いてなかったのですが、frontのコンテナはSSRではなくて単にクライアントにJSを渡すだけなんでしょうか。 はい。 > それであればクライアントからの通信なのでおっしゃるとおりこの構成自体が頓挫します。 やはりこの構成では無理みたいですね。私はプログラミング初心者なのでSSRという言葉を初めて聞きましたが、もっと詳しく前提条件を記述していれば良かったです。本当にすみませんでした。構成を変えて(AWSを使うか分からないですが)再度デプロイに挑戦し直そうと思います。貴重なお時間を割いて頂きまして誠にありがとうございました。
yu_1985

2022/08/30 12:38

まあ、厳密に言うとできないことはないんですけれど面倒なだけですし、こんな構成にしていたら間違いなくその理由を聞きますね。 docker-composeを使いたいのであればまずはALBを使うのをやめて普通にパブリックサブネットに1台インスタンスを配置して動かすだけでやってみるといいと思います。 冗長化云々はどれが何をやっているのか理解してからですね。
guest

0

https://(ドメイン):3001/api/v1/auth/sessions net::ERR_CONNECTION_REFUSED

このドメインとはALBに設定したのでしょうか。
それであればALBで3001をListenしていなければエラーになります。
また、そもそも内部だけで済む通信をわざわざインターネットに出す必要もありません。
リクエストを送る先が間違っているかと思います。

そもそも同サーバー内でrailsのコンテナとフロントのコンテナを双方動かしているのであればlocalhostにさえアクセスできれば動くはず(※)なので、ALBとかEC2とかは無視してまずは自サーバーのみで動く状態にしてください。
※それがあるべき構成かは一旦ここでは置いておきます。


以下、試したことに対して

1 踏み台サーバからアクセスできるか

肝心の試したことが伏せている部分によって不明なのでなんとも言えませんが、EC2インスタンスのプライベートIPに対してhttpでアクセスしたのならただしく動作しそうです。

2 セキュリティーグループの設定に3001を設定

どこのセキュリティグループというのを明記して欲しいところですが、仮にALBのセキュリティグループに総設定したとしてもそもそもALBが3001でListenしていなければエラーになりますし、上述のように今回リクエストを送るべき先は前段にあるALBではありません。

3 同一ec2(webサーバ)に向けてaxiosを設定
baseURL: "https://(伏せさせていただきます。):3001/api/v1

まず、railsはhttpsを受け付けてないと思われるのでhttpsでアクセスしようとするのが違うと思います。
前段にnginxでも置いてhttps化すれば話は別ですが、この構成でrailsが受け付ける通信は同サーバー内のfrontコンテナからの通信なのでこのためにわざわざ証明書を発行することはないでしょう。

EC2のグローバルIP(踏み台サーバのもの):3001

これはWEBサーバーも動かしてないでしょうしセキュリティグループでも許可してないでしょうからブラウザでアクセスはできないでしょう。
そもそも踏み台に対するアクセスが可能かどうかを確かめてもアプリケーションが動いている環境ではないので関係がありません。

2 ロードバランサーのグローバルIP:3001

前述の通りの理由でエラーになります。
またALBのIPは非固定なのでどのみちこのパターンは成り立ちません。

・1のように踏み台サーバにssh接続してアクセスは可能だが、検索バーに「EC2のグローバルIP(踏み台サーバのもの):3001」このような形で入力して検索するとアクセスできないのはなぜか分からない

それはアクセスしているのが踏み台で、WEBサーバーとは何も関係がないからです。
踏み台サーバーでプロキシの設定をしてWEBサーバーにリクエストを流すようにしているなら話は別ですが、普通そんなことはしません。(ALBを使っているにも関わらずやる理由がない)
アクセスしているのが踏み台サーバーなので踏み台サーバーで3001ポートのリクエストを受け付けるように何かしら設定をしていなければエラーになりますし、それにWEBサーバーは関係ありません。

・まず、そもそもこの構成でaxiosによるコンテナ間の通信は可能なのか

結局同サーバー内のコンテナ間で通信できれば良いのでサーバー1台構成とやることは変わりません。
そうしたくないのであればまずdocker-composeで同サーバー内に複数のコンテナを立ち上げる構成を見直すべきですが、今回やりたいことの範疇外なのでここでは一旦言及しません。

・参考にしたサイトではAPIを叩いていなかったので分かりませんが、APIとReactの通信もルーターに設定しないといけないのでしょうか?

これが何を指しているかわかりませんが、前述の通り今回は同サーバー内のコンテナ間で通信できれば良いので、普通にローカルでdocker-composeを動かすのと同じように設定してみてください。

今回は一旦きちんと動かすことを前提にまずdocker-composeをちゃんと動く状態にしましょうといいましたが、構成には改善の余地があるので今の課題を解消したら考えてみてください。

投稿2022/08/30 10:18

yu_1985

総合スコア7447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問