Streamlit アプリをデプロイする

Lizard (lizard.build) は、ローカルで使うのと同じコマンド streamlit run app.py で Streamlit アプリを実行します。このコマンドに --server.address 0.0.0.0 と 8501 などの固定ポートを付けて Procfile の web: 行に書き、lizard up --port 8501 でデプロイします。Procfile がない場合、lizardpack は python app.py を起動しますが、これは警告を出して終了するだけで、アプリを配信しません。

テスト状況: 以下のサンプルは Streamlit 1.65.0 を使ってローカルで動作し、データベース版は psycopg 3.3.5 を使って PostgreSQL 14 に対して動作しました。ビルドプランは、Lizard が使う lizardpack で確認しました。デプロイ手順は、まだ最初から最後まで試していません。ブラウザーは Streamlit との WebSocket を開いたままにしますが、Lizard のルーティングを通したその接続はまだ確認していません。

始める前に

  • アプリのテストに使う、手元のコンピューターの Python 3。
  • lizard login でサインイン済みで、Pro または 7 日間の Pro トライアル(カードが必要)を利用している Lizard CLI。料金を参照してください。

最小構成のアプリ

app.py:

import streamlit as st
 
st.title("Hello from Streamlit on Lizard")
name = st.text_input("Your name", "world")
st.write(f"Hello, {name}!")

requirements.txt:

streamlit==1.65.0

.python-version:

3.13

Procfile:

web: streamlit run app.py --server.port 8501 --server.address 0.0.0.0

ローカルで実行します:

python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
streamlit run app.py

Streamlit は http://localhost:8501 で開きます。.venv/、.env、.streamlit/secrets.toml を .gitignore に追加してください。

lizardpack がビルドするもの

ステップ内容
検出requirements.txt、pyproject.toml、Pipfile、または任意の .py ファイル
Python のバージョン.python-version、次に .tool-versions、次に pyproject.toml の requires-python。使われるのはメジャーとマイナーだけで、python:<x.y>-slim 上でビルドされます。デフォルトは 3.13。
インストールpip install -r requirements.txt。uv、Poetry、Pipenv の lock ファイルや設定ファイルがある場合はそれらを使用
起動Procfile の web: 行
ランタイムPYTHONUNBUFFERED=1。print の出力がすぐにログに届きます

サービスポートは --port で決まり、Procfile の --server.port と一致している必要があります。バージョンのルールと注意点については、ランタイムバージョンを参照してください。

デプロイ

アプリのフォルダーから実行します:

lizard init --name streamlit-app
lizard add --service web
lizard up --service web --port 8501

lizard up はフォルダーをアップロードし、Lizard 上でビルドして URL を表示します。git リポジトリ内では .gitignore に書かれたものをスキップします。git の外では .env ファイルもアップロードします。git push to deploy を使う場合は、GitHub リポジトリを接続 し、lizard port 8501 --service web でポートを設定してください。

シークレットと設定

st.secrets は .streamlit/secrets.toml を読み取りますが、このファイルはアップロードしないでください。Lizard では、シークレットをサービスの変数として保存し、環境変数から読み取ります:

lizard secrets set OPENAI_API_KEY=sk-... --service web
import os
 
api_key = os.environ["OPENAI_API_KEY"]

変数を変更すると、再ビルドなしでアプリが再起動します。変数とシークレットを参照してください。

Managed Postgres を追加する

lizard add postgres
lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service web

シングルクォートで囲むと、シェルは ${{…}} を解釈しません。Lizard はデプロイ時に 参照 を解決します。requirements.txt に psycopg[binary]==3.3.5 を追加し、サーバープロセスごとに接続を 1 つ開きます:

import os
 
import psycopg
import streamlit as st
 
 
@st.cache_resource
def get_conn():
    return psycopg.connect(os.environ["DATABASE_URL"], autocommit=True)
 
 
with get_conn().cursor() as cur:
    cur.execute("SELECT now()")
    st.write("Database time:", cur.fetchone()[0])

st.cache_resource により、再実行やブラウザーセッションをまたいで接続が保持されます。データは Managed Postgres か Managed Object Storage に保存してください。アプリがコンテナ内に書き込んだファイルは、次のデプロイで失われます。

動作を確認する

lizard logs --service web --tail 100
lizard domain --service web
curl https://<your-domain>/_stcore/health

ログには You can now view your Streamlit app in your browser が表示され、ヘルス URL は ok を返します。アプリの URL を開いてテキストボックスを変更すると、あいさつ文が更新されるはずです。

よくある問題

症状対処
ログに to view this Streamlit app on a browser, run it with the following command と表示されるProcfile がないか web: 行がないため、lizardpack が python app.py を実行しました。
デプロイがいつまでも healthy にならないサービスポートと --server.port が違います。lizard port --service web を実行してください。サービスが healthy にならないを参照してください。
ModuleNotFoundErrorパッケージを requirements.txt に追加し、もう一度デプロイします。
シークレットの KeyErrorweb サービスに変数がありません。lizard secrets list --service web で確認してください。
ページに接続中のメッセージが表示されたまま読み込まれないブラウザーが /_stcore/stream への WebSocket を維持できていません。ブラウザーのコンソールで失敗したそのリクエストを探し、lizard logs でエラーを確認してください。

関連項目

更新日