21
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS上にStreamlitの動作環境を作ってみた

Last updated at Posted at 2022-09-23

概要

Streamlit という Python のWEBアプリケーションフレームワークを動かすための環境をAWS上に作ったのですが、とにかく詰まりに詰まったので覚えている範囲で記録を残しておこうと思います。誰かしらのお役に立てば幸いです。

ということでいってみましょう。

EC2環境

  • Amazon Linux 2
  • Apache 2.4.54
  • Python 3.7(Amazon Linux 2 に最初から入っていた)

インフラ構成

大まかにはこんなかんじですが特に凝ったことはしていません。
アベイラビリティゾーンやパブリックサブネットは実際は複数ありますが、本筋にあまり関係ないのでここでは省略してます。

aws.png

唯一の注意点として、 ロードバランサーを置く場合は必ず Application Load Balancer を使ってください。

理由は、Streamlit はページ上に表示するメインコンテンツは WebSocket で取得しているのですが、WebSocketに対応しているロードバランサーが Application Load Blancer のみ であるためです。

ちなみに私はそこに気が付かず、ずっと Classic Load Balancer を使い続けていて、ページは表示するのにずっと Please wait 表示でコンテンツが出ないことに何日もハマっていました。いろいろ切り分けして、ロードバランサー側の問題というところに辿り着いたあと、下記の記事を見つけて「そもそもクラシックロードバランサーだとだめなのでは?」という考えに至った次第です。

EC2側の設定

単に私がそこそこ慣れているというだけの理由で今回は Apache 2.4 でWEBサーバーを立てています。簡単に設定内容を記載します。

# Apacheインストール
$ sudo yum install httpd
# バーチャルホスト追加
$ sudo vim /etc/httpd/conf.d/streamlit_app.conf
# Apache起動
$ sudo systemctl start httpd
# 自動起動有効化
$ sudo systemctl enable httpd

confの内容は以下のとおりです。
ロードバランサー側で 443 → 80 への転送を行っているため、EC2側では80番の設定のみ記載しています。なお、ドメインとドキュメントルートは必要に応じて読み替えてください。

/etc/httpd/conf.d/streamlit_app.conf
<VirtualHost *:80>
  ServerName yourdomain.net
  DocumentRoot /var/www/your_app/

  # Streamlit のアプリケーションが8501ポートで待ち受けているため
  # そっちに転送するための設定です
  # WebSocket通信を行う際のリクエスト先が /stream であるため、
  # /stream のみ ws に変更し、それ以外は http のまま転送します
  ProxyPreserveHost On
  ProxyPass / http://localhost:8501/
  ProxyPassReverse / http://localhost:8501/
  <Location "/stream">
    ProxyPass ws://localhost:8501/stream
    ProxyPassReverse ws://localhost:8501/stream
  </Location>
</VirtualHost>

Streamlitの設定

Amazon Linux 2 環境では最初から Python 3.7 と pip3 が使えましたので Python のインストール周りについては省略します。

インストール

$ pip3 install streamlit
$ pip3 install plotly_express

streamlit だけをインストールしても
ModuleNotFoundError: No module named 'plotly_express' と怒られてしまい、公式のデモアプリすら動かないので plotly_express もインストールしておきましょう。

設定ファイルの追加

必須ではありませんが、コマンドラインオプションの指定が面倒な方は作っておくと楽です。
~/.streamlit/config.toml を作っておくと streamlit コマンド実行時に勝手に指定されます。

~/.streamlit/config.toml
[server]
# streamlit側のリスナーポート
# デフォルトと同値ですが環境によって8502になっていたりする事例があるので一応明示的に指定しています
port = 8501 

# サーバー側のファイル変更時に即座に反映させます
# 毎回手動で run しなおすのは面倒なので特に理由がなければ指定しておくといいと思います
runOnSave = true 

# これがないとws通信時に一部のヘッダが削除されるようで、
# それが原因で今回の環境下ではコンテンツの取得に失敗していましたため追加しています
enableWebsocketCompression=false

[browser]
# 統計情報の送信をオプトアウトする設定です
gatherUsageStats = false

他の設定項目について知りたい方は公式サイトを参考にしてください。

公開

単純に streamlit run %your_app_entrypoint.py% を実行すれば公開されますが、そのままだとサーバーからログアウトできないので、公式フォーラムに載っていた以下の方法を採用して、tmuxで別セッションを立ち上げて公開しています。

# tmux のインストール
$ sudo yum install -y tmux
# streamlit の公開に使うセッションを作成
$ tmux new -s StreamSession
# アプリ公開(helloworld.pyの部分は読み替えてください)
$ streamlit run helloworld.py

ページが表示できれば完了です。おつかれさまでした:relaxed:

st_2.png

おまけ

streamlit 公開時に Please wait がずっと表示され続けていて困っている例はけっこう多いみたいです。例にもれず私も同じ問題で詰まりました。原因はいろいろあると思いますが、主に以下のあたりを疑うと解決するかもしれません。

  • 公式が挙げているよくある原因 に該当している(詳しくはリンク先)
  • Apache, Nginx の転送ミスをしている(特に /stream の転送ができているかどうか)
  • Classic Load Balancer (CLB) を使っている(私だけ?)

お世話になった参考リンク様

21
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?