【AWS】Streamlitで作成したRAGアプリケーションをEC2にデプロイし、HTTPS化して安全に公開する方法を丁寧に解説
参照
概要
業務の中で、Streamlitで作成し、EC2にデプロイしたRAGアプリケーションを以下の要件で実装する必要があり、その際得た知見を整理してブログの形にまとめました。
- お名前.comで作成したドメインと紐付け、ネームサーバーの管理はAmazon Route 53 上でできるようにする
- HTTPS経由でセキュアにアクセスしたい
Streamlit Cloudでもデプロイできるのでは?という意見もあるかと思われますが、今回は「敢えて」EC2でデプロイする方法を実施しています。(詳細は後述)
前提) EC2上に構築したStreamlitアプリの特徴
- EC2上でStreamlitアプリを起動すると、デフォルトでは
http://
で起動してしまうので、安全性の観点で少し不安が残る
→顧客要件で、http://
でのアクセスは許可されておらず、https://
でのアクセス設定が必要な場合も考えられる。
事前準備
お名前.comでドメインを払い出す、Route 53にドメイン管理を移管
今回は検証用に、お名前.comでmaeno-dev.com
というドメインを取得しました。
ホストゾーンの作成
Aレコードの作成
NSレコードの確認
ネームサーバーの管理を、お名前.comからRoute 53に移管するために設定変更
お名前.comの、ドメイン
メニューから、ネームサーバー設定を選択し、ドメインを選択し、その他のネームサーバーを使う
という部分で、先ほどの画面で表示されていた4つの名前を記載します。
デプロイ用のEC2の作成、ローカルで作成したソースコードの移植
VPC作成
EC2作成
作成したVPC、サブネットを選択。
インスタンスタイプはデフォルトの選択のままで進めます。
セキュリティグループは、HTTP化対応を行うまでは、自身のIPアドレスに加えて、HTTPS/HTTPで、全てのIPを許可しています。(おそらく、SSL証明書を発行する際、外部の認証機関からアクセスが入るため、自身のIPのみの許可では上手くいかなかった)証明書の設定が完了後、以下のルールを削除しました。
基本的には許可したいIPのみを指定し、安全にアクセスができるようにしましょう。
ローカルで作成したRAGアプリケーションをclone
ローカルで作成したソースコードをpullするために、gitをインストールします。
$ sudo yum install git-all
その後、
$ ssh-keygen -t rsa
で認証鍵を生成、公開鍵をGitHubに登録することで、EC2とリポジトリ間でSSHを可能にします。
その後以下コマンドでソースコードをcloneします。
$ git clone git@github.com:y-mae-dev/streamlit-rag-app.git
手順
0.RAGアプリケーションをローカルで準備
今回は Streamlit×Bedrock×Kendraで作る! 多機能チャットボットで紹介したアプリを使用します。(※一部アップデートを加えております。記事の本旨から逸れるためここでは解説しませんが、「参考)ソースコード」の項でソースコードは記載いたしますので参考にしていただければと思います。)
1.ローカル→作成したEC2インスタンスにSSH
.ssh/config
配下に 以下を記載しておきます。
Host streamlit-rag-app
HostName (EC2のパブリックIPアドレス)
User ec2-user
Port 22
IdentityFile ~/.ssh/(秘密鍵の名前)
$ ssh streamlit-rag-app
そうすることでEC2へアクセスできるようになります。
2. サーバー側でのリバースプロキシの設定
EC2でStreamlitを起動し、独自ドメインでHTTPS接続するまで(備忘録)
を参考にさせていただきました。
ここが今回の肝になります。
2.1 nginxのインストール
sudu yum install nginx 実行結果
2.2 nginxの起動
[ec2-user@ip-10-0-0-10 ~]$ sudo service nginx start
Redirecting to /bin/systemctl start nginx.service
2.3 設定ファイルの修正
2つのディレクトリを作成し、設定ファイル(nginx.conf
)を一部変更します。
$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled
$ sudo vi /etc/nginx/nginx.conf
include /etc/nginx/conf.d/*.conf;
の下に、
include /etc/nginx/sites-enabled/*;
を追加
$ sudo chmod 777 /etc/nginx/sites-available
$ sudo chmod 777 /etc/nginx/sites-enabled
を実行し、フォルダ内の権限を変更
[ec2-user@ip-10-0-0-10 ~]$ echo '''server {
listen 80;
server_name maeno-dev.com;
location / {
proxy_pass http://0.0.0.0:8501/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}''' > /etc/nginx/sites-available/maeno-dev.com
を実行し、nginxのルーティング設定を追加します。
これによって、httpのアクセスが8501にルーティングされます。
(streamlit-rag-app) [ec2-user@ip-10-0-0-10 streamlit-rag-app]$ streamlit hello
Collecting usage statistics. To deactivate, set browser.gatherUsageStats to false.
Welcome to Streamlit. Check out our demo in your browser.
URL: http://maeno-dev.com:8501
Ready to create your own Python apps super quickly?
Head over to https://docs.streamlit.io
May you create awesome apps!
表示されているURLにアクセスしてみると、以下のような画面になり、通信が転送できていることがわかります。
streamlit hello
を実行すると、streamlitが提供するWelcomeページに遷移します。
ここまではhttp接続を行い、アプリを起動できる状態にしました。
しかしながら、本記事の目的はhttps接続できるようにすること
でした。続いてのステップとして、無料かつ自動でSSL証明書を発行できるツールであるcertbotを使って、SSL証明書を発行し登録します。
まずは、certbotをインストールします。(実行結果は以下)sudo yum install certbot-nginx実行結果
続いて、以下コマンドを実行します。
$ sudo certbot --nginx
このコマンドは、Let’s Encrypt を使って SSL/TLS 証明書を取得し、自動的に Nginx に設定を追加するものです。以下が実行結果(一部)です。
[ec2-user@ip-10-0-0-10 ~]$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): maeno-dev.com
Requesting a certificate for maeno-dev.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/maeno-dev.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/maeno-dev.com/privkey.pem
This certificate expires on 2025-03-31.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Could not install certificate
NEXT STEPS:
- The certificate was saved, but could not be installed (installer: nginx). After fixing the error shown below, try installing it again by running:
certbot install --cert-name maeno-dev.com
Could not automatically find a matching server block for maeno-dev.com. Set the `server_name` directive to use the Nginx installer.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
どうやらSSL証明書は登録できましたが、nginxにインストールできなかったようです。
もう一度手順を見直してみたところ、下記二つの対応が漏れていたようでした。
- 仮想ホスト
maeno-dev.com
の設定を有効化 - nginxの再起動を行い、設定の反映
ln -s /etc/nginx/sites-available/maeno-dev.com /etc/nginx/sites-enabled/maeno-dev.com
[ec2-user@ip-10-0-0-10 ~]$ sudo service nginx restart
Redirecting to /bin/systemctl restart nginx.service
Successfully deployed certificate for maeno-dev.com to /etc/nginx/sites-enabled/maeno-dev.com
Congratulations! You have successfully enabled HTTPS on https://maeno-dev.com
上記のように、最終的に You have successfully enabled HTTPS on https://(ドメイン名)
というような表示が出ればHTTPS化の作業は完了です。
4.Streamlitアプリを起動、https://ドメイン名
でアクセスできるか確認
画面のように、ドメイン名を当てた状態で、サンプルアプリケーションを起動できたことが確認できました。
ここでTips
nohup streamlit run app.py &
とすれば、アプリをバックグラウンドで常時起動することができます。
バックグラウンドで起動しない場合、以下のような問題が発生します。
- ローカル→EC2との接続が切れてしまった際にアプリとの接続も切れてしまう
- ターミナルが操作できない(アプリ起動時に、別ターミナルを開かないと、他のコマンドが打てない)
そのためアプリケーションを実際に誰かに公開する場合は、バックグラウンドで常時起動させておくのが運用上よいと思います。
EC2 vs Streamlit Community Cloud
EC2にStreamlitアプリをデプロイする場合と、Streamlit Community Cloudを比較するべく、セキュリティ、労力、コストの観点から比較してみました。
安全性を重視したいならEC2へのデプロイ、お手軽さを重視したいならStreamlit Community Cloudへのデプロイが良さそうですね。
比較項目 | EC2へのデプロイ | Streamlit Community Cloudへのデプロイ |
---|---|---|
セキュリティ | ・SGにおいて、特定IPによるアクセス許可を実施することでアクセス 制限が可能 ・HTTPS対応や証明書の管理が 手動 | – 基本的なセキュリティはStreamlit側で管理なので、サーバーや証明書の更新作業は不要。 ・アプリはインターネット上に公開されるためアクセス制限は基本的に難しい |
労力 | ・サーバーのセットアップや環境構築が必要。 | 非常に簡単にデプロイ可能 |
コスト | ・EC2の利用料が発生 | ・無料。ただし、サービスの制限(作成できるリソースなど)がある |
参考)ソースコード
完全版はGithubに公開しています。app.py
kendra_bedrock_query.py
app_config.py
.env
まとめ
いかがでしたでしょうか。
手順は少し煩雑ですが、要点を理解すればそこまで難しくないと思います。作成したアプリケーションをよりセキュアに公開したいという場合は、本記事でご紹介した方法を試してみるのはいかがでしょうか。
本記事が皆さんのお役に立つことができれば幸いです。