Streamlit with Google Cloud: Hello, world!
Streamlit、とても便利ですよね!小さなアプリとしても、データ可視化にしても。
連載を通して、Google Cloud 上で Streamlit を上手に動かす方法をご紹介します。
- Cloud Run での Hello, world! (本記事)
- Firebase 認証との連携
- BigQuery へのクエリ
- GitHub、GitLab、Cloud Build での CI/CD
Streamlit?なぜ Google Cloud で?
Streamlit は「データ分析スクリプトを、数分で "共有できる Web アプリ" に変える」というキャッチコピー通り、Python で書かれたロジックをそのまま、直感的に、フロントエンドの経験がない人でも数分で Web アプリケーションにしてしまえるようなとても優れたフレームワークです。
まずはぜひ、公式サイトのギャラリー の一例を見てみてください。 (↑ このサンプルのソースコードはこちら)
そして実際、これをクラウドで使いたいというお問い合わせが最近とーっても増えています。
たしかにそもそも Streamlit が「分析ツールをチームで共有する」ためのものですし、アプリケーションをクラウドで気軽 & 安全に共有できれば抜群に相性がよさそうです。そんなわけで本記事では、以下の点を意識しながら Streamlit を Google Cloud にのせるための方法をお伝えします。
- 極力運用の手間がかからないこと
- 認証認可含め、セキュアな方法で共有できること
- コードを書いて git push したらアプリが更新されること
Cloud Run に Streamlit をのせる
1. ローカルでの起動
すでに Streamlit アプリが手元にあれば読み飛ばしてください。一方、もし Streamlit を使ったことがなければ以下 3 行を実行してみてください。$PATH
または Python 仮想環境が正しく設定できていれば Web アプリが起動します。
pip install streamlit
echo 'import streamlit as st;st.text("Hello, world!")' > home.py
streamlit run home.py
2. 設定ファイルの確認
依存関係を定義した requirements.txt
は手元にありますか?なければ用意しましょう。1. で初めて Streamlit を使った方であれば、以下のコマンドでも OK です。
echo 'streamlit' > requirements.txt
また、requirements.txt
の隣に Dockerfile
はありますか?もしなければ、せっかくなので Dockerfile なしにコンテナとして動かす 体験をしてみましょう。以下のコマンドで Procfile
を作ります。
echo 'web: streamlit run home.py --server.port ${PORT:-8080}' > Procfile
3. Google Cloud 側の準備
もし手元で gcloud CLI が使えなければインストールしてください。CLI が用意できたら、改めて認証を通し、デプロイ先のプロジェクトを設定しましょう。
gcloud auth login
gcloud config set project <your-project-id>
クラウドで利用するサービスを有効化しましょう。
gcloud services enable compute.googleapis.com run.googleapis.com \
artifactregistry.googleapis.com cloudbuild.googleapis.com
上記コマンドで有効化されるサービスは以下の通りです。
-
compute.googleapis.com
▶︎ Compute Engine、仮想マシンが利用できます。 -
run.googleapis.com
▶︎ Cloud Run、コンテナアプリをホスト。 -
artifactregistry.googleapis.com
▶︎ Artifact Registry、Docker イメージ の保存。 -
cloudbuild.googleapis.com
▶︎ Cloud Build、サーバーレスな CI 環境です。
4. Cloud Run へのデプロイ
ソースコードをクラウドに転送し、Dockerfile なしにコンテナとしてビルドし、Artifact Registry にそれを保存した上で Cloud Run で起動、誰からでもアクセスできるよう IAM を設定するコマンドは以下の 1 行です。
gcloud run deploy my-app --region "asia-northeast1" --source . \
--allow-unauthenticated --quiet
5 分ほど待ちます。コーヒーを淹れてきてもいいかもしれません。
ちなみに Dockerfile
がない場合、コンテナのビルドには Buildpacks が使われます。便利ですね!
一連の処理がうまくいくと、ログの最後に URL が表示されます。アクセスしてみてください。以下のような出力が出たら、おめでとうございます!クラウドに Streamlit アプリケーションをホストできました 🎉🎉🎉
Poetry による依存管理・デプロイ
requirements.txt
で依存関係がうまく解決できなくなった経験はありませんか?また Python の仮想環境を意識した開発がちょっと煩雑だったり。そんなときはそれらを改善できる依存関係管理ツール Poetry の出番です。ここではその詳細には触れませんが、Poetry を前提にしたとき、Streamlit や Cloud Run とどう組み合わせるのがいいのかをみていきます。
1. Poetry で Streamlit をインストール
Poetry の公式ガイドを見つつインストールしましょう。作業フォルダに移動し、 init
コマンド で設定ファイルを作ります。
poetry init
パッケージは add
コマンド でインストールできるのですが、Streamlit を入れようとするとエラーが起きると思います。
poetry add streamlit
もし手元の Python 環境が 3.9 の場合、出力をよく読むと a possible solution would be to set the python property to ">=3.9,<3.9.7 || >3.9.7,<4.0"
というメッセージがでているかもしれません。その場合は Poetry の設定ファイルを提案通りに書き換え、改めてインストールしてみます。(Python 3.11 であれば以下は不要なはずです)
sed -i '' -e 's/python.*/python = ">=3.9,<3.9.7 || >3.9.7,<4.0"/g' pyproject.toml
poetry add streamlit
インストールされましたか?仮想環境にインストールされたコマンドは run
コマンド で実行できます。Streamlit のバージョンを確認してみましょう。
poetry run streamlit version
後で必要なら export
コマンド で requirements.txt
を生成することもできるので、requirements.txt
は消してしまいましょう。
rm requirements.txt
2. 静的解析ツールの導入
アプリケーションをテストする一環として、静的解析ツールや脆弱性検証ツールを導入してみましょう。実行環境では使わないので dev
グループとして導入します。
poetry add --group dev isort black flake8 pip-audit
先々ローカルと CI で同じテストがしやすいよう、スクリプトにまとめつつ、実行してみます。
cat << EOF > test.sh
#!/bin/sh
set -e
poetry run isort .
poetry run black .
poetry run flake8 --exclude=.venv .
poetry run pip-audit
EOF
chmod +x test.sh
./test.sh
3. Dockerfile の作成
Buildpacks では内部的に requirements.txt
が参照されるため、Poetry の export
コマンド を組み合わせればビルドできることもありますが、ここから先は厳密な依存関係が尊重されるよう、Buildpacks は諦め、Dockerfile を書きます・・
FROM python:3.11 as builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
POETRY_HOME="/opt/poetry"
ENV PATH="${POETRY_HOME}/bin:${PATH}"
RUN python -c 'from urllib.request import urlopen; print(urlopen("https://install.python-poetry.org").read().decode())' | python -
RUN poetry config virtualenvs.create false
WORKDIR /app
COPY pyproject.toml /app/
COPY poetry.lock /app/
RUN poetry install --no-interaction --without dev --no-ansi --no-root -vvv
FROM python:3.11-slim
ENV PYTHONUNBUFFERED=1 \
PYTHONIOENCODING="UTF-8"
COPY /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY /usr/local/bin/streamlit /usr/local/bin/
WORKDIR /app
COPY . /app/
CMD ["streamlit", "run", "home.py", "--server.port", "8080"]
ポイントは以下です。
- マルチステージ ビルドを使い、最終的なイメージからは Poetry への依存をなくす
- ステージ間で依存をうまく引き渡すため、Poetry の仮想環境は作らない
- 実行環境で不要なパッケージを除外すべく poetry install は
--without dev
- Cloud Run で動作するよう、起動ポートには 8080 番を指定
Cloud Run は内部的に イメージ ストリーミング という技術が使われていて イメージサイズによる起動時間への影響はとても小さいのですが、リンク先にあるようなセキュリティ観点、その他費用やイメージの持ち運び観点でも、何かと小さいほうが便利ではありますよね。ということで最後に、不要となった Procfile は消しておきましょう。
rm Procfile
4. Cloud Run へのデプロイ
Poetry を導入してみましたが、Dockerfile を作りビルドもできる状態です。最後にもう一度、Cloud Run にデプロイしてみましょう!
gcloud run deploy my-app --region "asia-northeast1" --source .
ちなみにですが、ローカルで起動する場合は以下のコマンドを実行すれば OK です。
poetry run streamlit run home.py
いかがでしたか?アプリケーションはうまくクラウドで動いたでしょうか?次は Firebase 認証を使って、簡単なログイン機能を実装してみます。
Discussion