AmplifyのフロントエンドサーバからEC2のバックエンドサーバへの通信ができません!
掲題の件についてAIと壁打ちしながら解決したことを備忘録を兼ねて記録します!
前提
前提として、フロントエンドのサーバをAmplifyにデプロイし、バックエンドのコードとデータベースをEC2にデプロイする運用を行っていました。curlコマンドでアプリケーションが動作することは確認済みです。
発生した問題
フロントエンドアプリケーションからの通信で、以下のエラーメッセージが表示されました。
'https://~~~’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint
これは、HTTPSで提供されているサーバ(Amplify)からHTTPで提供されているサーバ(EC2内のサーバ)にアクセスした際に、プロトコルが異なるため発生するエラーです(Mixed Contentエラー)。
試したこと1
単純にリクエスト送信先をhttps://<EC2のIPアドレス>
のように変更しました。
しかし、EC2インスタンス側でHTTPS通信を受け付ける設定がされていないため、当然ながらうまくいきませんでした。
試したこと2
バックエンドのサーバ(EC2インスタンス上で動作しているアプリケーション)をHTTPSを指定して起動しました。
これにはNode.jsのhttps
モジュールを使用したり、証明書を用意したりする必要があり、設定が複雑になりがちです。
解決策: リバースプロキシ
フロントエンドはそのままAmplifyでデプロイし、EC2インスタンスでは最初にHTTPSで提供されるリバースプロキシ(Apache)でリクエストを受け付けます。
クライアント(Amplify)からのHTTPSリクエストをリバースプロキシが受け取り、証明書を使って通信を復号した後、同じEC2インスタンス内のバックエンドサーバへHTTPでリクエストを転送(ルーティング)します。
設定手順の概要
- Apacheサーバを構築します。サーバはインスタンス起動と同時に起動させたいため、自動起動を設定します。
sudo systemctl start httpd
sudo systemctl enable httpd
- AWS Route 53などでドメインを取得します。
- フロントエンドでのリクエスト送信先を
https://<ドメイン名>/<任意のパス>
のような形式にします。 - EC2インスタンスのセキュリティグループで、HTTPS(ポート443)とHTTP(ポート80)のアクセスを許可します。EC2インスタンスに届いたHTTPS通信は、まずポート443で処理されるためです。
- Apacheがポート443で指定ドメインからのリクエストを処理するように設定します。
- SSL証明書の取得とApacheへの設定を自動化するためにCertbotを使用します。
- リバースプロキシの設定を調整します。
httpd.conf
などの設定ファイルを編集し、以下のように記述します。これにより、<ドメイン名>/api
へのリクエストが、EC2インスタンス内のlocalhost:3000でリッスンしているアプリケーションにルーティングされます。
ProxyPass /api http://localhost:3000/
ProxyPassReverse /api http://localhost:3000/
問題点
- ドメイン取得: SSLを利用する場合、基本的に独自ドメインが必要です。お名前.comやGoogle Domainsなどで取得できます(年額数百円〜)。
代替案: フロントエンドもEC2でホストする
フロントエンドのアプリケーションもビルドし、静的ファイルとしてEC2インスタンス上のWebサーバ(NginxやApacheなど)でホストします。
この場合、フロントエンドとバックエンドが同じオリジン(または同じプロトコル)で提供されるため、Mixed Contentエラーは発生しません。
メリット
- 構成がシンプルになります。
- EC2に統合できるため、アプリケーションによってはコストを削減できる可能性があります。
デメリット
- デプロイ: Amplifyのような簡単なデプロイフロー(Git連携など)は利用できなくなります。手動でのファイル配置や、CI/CDパイプライン(例: CodePipeline, GitHub Actions)を自前で構築する必要があります。
- スケーリング/可用性: Amplifyが提供するCDNやスケーリングの恩恵を受けられません。自前で設定する必要があります。
- 開発体験: Amplifyの便利な機能(環境変数管理、プレビュー機能など)が利用できなくなります。
まとめ
Amplifyの利便性を活かしたい場合は、Apacheなどのリバースプロキシを用いてHTTPS化するのが推奨されます。初期設定の手間や若干のコストはかかりますが、モダンなWebアプリケーションの構成としては一般的です。
コストを最優先する場合や、CI/CD、スケーリングなどを自前で管理できる場合は、フロントエンドもEC2でホストする代替案も検討できます。
プロジェクトの要件、予算、チームのスキルセットに応じて最適な方法を選択することが重要です。