EC2にdocker composeでコンテナ内で接続しようとしたときにnet::ERR_CONNECTION_REFUSED

未分類

本記事では、ec2インスタンス内にdocker composeを導入し、アプリ間で接続しようとした時に、net::ERR_CONNECTION_REFUSEDエラーが発生してしまい、アプリを正常起動することができませんでした。

  • 今回の構成
  • EC2内に立てるコンテナ:app(frontendアプリ(vue))、api(backendアプリ(rails))、db(mysql)
  • EC2内のリバースプロキシ:nginx

今回のエラーは、vueで作成したfrontendアプリからrailsで作成したbackendアプリに対してリクエストを送った際に発生しました。今回はこの問題の原因の追求と、その対策を行いました。

現状のおさらい

まずはできているところとできていないところのおさらいから

  • ブラウザからドメインを入力してfrontendアプリの表示→できる
  • ec2コンテナ内でcurlを使用したbackendアプリへのリクエスト→できる
  • frontendアプリからbackendアプリへのリクエスト→できない

バックエンドアプリは正常に起動できていることは確認できており、frontendアプリには、そのurl(http://localhost:3000)に対してリクエストを送っているのにエラーが発生してしまいます。

net::ERR_CONNECTION_REFUSEDの原因

原因は、nginxにbackendの設定をしていないのが原因でした。今回、backendコンテナは3000番portで起動しており、3000番portに対してlocationの設定を追加するとアクセスに成功。

       // frontendアプリへのアクセス
       location / {
            proxy_pass http://localhost:8080;  # 8080ポートにリクエストを転送
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }        
     ////////////////// ↓下記を追加  //////////////////
     // backendアプリへのアクセス
        location /api {
            proxy_pass http://localhost:3000;  # 3000ポートにリクエストを転送
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

ただし、backendアプリのルーティングは/api/配下に設定しないといけません。また、frontendアプリはapiへのリクエスト先をドメイン名/apiに設定しなおしましょう。

net::ERR_CONNECTION_REFUSEDのまとめ

今回、確認したところブラウザからバックエンドに疎通するためnginxに穴を開けることで解決しました。ただし、本来はfrontendアプリ以外からアクセスを受け付けてはだめなので、下記を検討する必要があります。

  • dockerコンテナ内でfrontend⇄backendのアクセスやりとりができるようになる。
  • ↑が無理ならfrontとbackを動かすEC2サーバーを分けてbackendコンテナをプライベートサブネット(インターネットが接続できないところ)に配置する

awsのベストプラクティスとしては下が適切だと思います。ただし、安価に済ませるためにはEC2コンテナ1台で稼働できるので、上の方法がいいかなと思います。

どちらにせよ、apiサーバーをインターネットには接続できないようにするべきなので、方法が見つかり次第、追記していこうと思います。

コメント

タイトルとURLをコピーしました