ポート80でStreamlitアプリケーションを実行する方法
Published on
Streamlitは、開発者が手間をかけずにインタラクティブなWebアプリケーションを作成できる強力なツールです。ただし、設定に関してはいくつかの課題があります。その中でも、ポート80でのアプリケーションの実行はよく遭遇する問題の一つです。この包括的なガイドでは、ユーザーの経験、専門家の知見、実践的な例を活用して、この課題に自信を持って取り組むための情報を提供します。
無料でデータ分析とデータの可視化アプリをStreamlitで作成したいですか?
PyGWalker (opens in a new tab)は、Pythonライブラリであり、StreamlitアプリにTableauのようなユーザーインターフェースを簡単に組み込むことができます。Coding is Fun (opens in a new tab)のSven氏によって制作された素晴らしいビデオをご覧ください。このビデオでは、強力なデータ可視化Pythonライブラリを使用してStreamlitアプリを強化するための詳細な手順が説明されています!
PyGWalkerコミュニティへのスヴェン氏と彼の素晴らしい貢献 (opens in a new tab)に特別な感謝を表します!
さらに、PyGWalkerのGitHubページ (opens in a new tab)もチェックしてみてください。PyGWalkerのさらなる例があります。
パート1:ポート80上でのStreamlitの設定の難しさ
2022年5月、StreamlitコミュニティのユーザーであるNom_jiは、アプリケーションをポート80で実行しようとした際に問題が発生しました。Nom_jiは公式のStreamlitドキュメントに記載されている設定手順を正しく実行しましたが、PermissionError: [Errno 13]
のエラーが発生しました。
興味深いことに、アプリケーションはポート8051や8080で完璧に動作しました。これから以下の重要なポイントが導かれます。
- すべてのポートは同じではありません。ポート80を含む1024以下のポートは、Unix系のオペレーティングシステムでは特権ポートと見なされ、通常はスーパーユーザー(またはルート)のアクセスが必要です。
Nom_jiの問題に対して、Streamlitの開発者関係の元責任者であるRandyzwitchは、ポート80が他のインスタンスによって使用されていないか確認することを提案しました。ターミナルでnetstat
コマンドを使用してポート上で既存のインスタンスを確認できます:
sudo netstat -tuln | grep :80
このコマンドは、ポート80で現在実行されているサービスをリストアップします。コマンドが出力を返す場合、ポート80が既に使用されていることを意味し、Streamlitアプリケーションをこのポートで実行する前に他のサービスを停止する必要があります。
パート2:Streamlitにおけるポート割り当ての探究
Streamlitユーザーが遭遇する可能性のある別の問題は、複数のStreamlitアプリケーションを同時に実行したい場合です。StreamlitコミュニティのモデレーターであるBeyondMyselfは、これに対する明確な解決策を提供しました:アプリケーションを開始する際に--server.port
パラメータを指定します。
例えば、streamlit run myapp.py --server.port 8080
というコマンドは、myapp.py
で定義されたStreamlitアプリをポート8080で実行します。8080の代わりに利用可能なポート番号を使用することができますが、すでに使用されているポートではないことを確認してください。
したがって、複数のStreamlitアプリを実行する場合は以下の点に注意してください:
- 各アプリケーションに固有のポート番号を割り当てること。
- 選択したポートが他のサービスによって既に使用されていないことを確認すること。
パート3:Streamlitアプリを標準ポートで実行する
Streamlitアプリを任意の利用可能なポートで実行することができますが、ドメイン経由で標準ポート(たとえば80番ポート)で実行されるようにしたい場合もあります。この場合、リバースプロキシの概念が重要になります。
リバースプロキシは、ApacheやNginxなどのWebサーバーからリクエストをあなたのStreamlitアプリが実行されているポートに転送することができます。以下の方法で設定することができます:
- ドメインへのすべてのリクエストをStreamlitアプリに転送する。
- Webサーバーを構成して、特定のサブディレクトリへのリクエストを異なるStreamlitアプリに転送する。
例えば、さまざまなポートで複数のStreamlitアプリを実行している場合、
mydomain.com/app1
をポート8000で実行しているStreamlitアプリに転送し、mydomain.com/app2
をポート8080で実行しているアプリに転送することができます。この設定により、ユーザーの視点ではアプリがポート80で実行されているように見えます。
パート4:Streamlitアプリに固定ポート番号を設定する
最後に、固定ポート番号を設定してStreamlitアプリに対して安定したリンクをチームメンバーやユーザーと共有したい場合があります。その際には./streamlit/config.toml
ファイルが重要です。
config.toml
ファイルで固定のポート番号を指定することができます。例えば:
[server]
port = 8501
この設定により、Streamlitは常にアプリを実行する際にポート8501を使用します。ただし、このポートが他のサービスによって使用されていない必要があります。そうでない場合、アプリは正常に実行されません。
まとめると:
- 特権ポートに対してスーパーユーザーアクセスを持つことを確認すること。
netstat
コマンドを使用してポート上の既存のインスタンスを確認すること。- 複数のアプリを実行するために
--server.port
パラメータを使用すること。 - リバースプロキシを利用してアプリがポート80で実行されているようにすること。
config.toml
ファイルを使用してポート番号を固定すること。
パート5:一般的なエラーの対処
上記の手順に従っても、ポートが予約されているというエラーなどの問題が発生する場合があります。このエラーは、他のプロセスが正しくシャットダウンされていないか、使用しようとしているポートで何か別のプロセスが動作している場合に表示されることがあります。
ポートが使用されているかどうかを調査するために、netstat
コマンドを使用できます。以下は、特定のポート(この場合はポート80)が使用されているかどうかをチェックするためのシンプルなコードスニペットです:
netstat -tuln | grep :80
出力において、目的のポート番号がリストされている場合、そのポートは既に使用されていることを意味します。Linuxシステムでは、lsof
コマンドを使用して特定のポートを使用しているプロセスを確認することもできます:
sudo lsof -i :80
プロセスを特定したら、kill
コマンドを使用して終了することができます。
kill -9 PID
PID
は前のコマンドで得たプロセスIDで置き換えてください。
ポートを使用している他のプロセスが存在しないことを確信し、それでもエラーが発生する場合は、オペレーティングシステムのネットワーク設定に問題がある可能性があります。その場合は、ITの専門家やStreamlitコミュニティから支援を求めることを検討してください。
パート6:Streamlitアプリケーションの最新情報を取得する
もう一つのチャレンジは、Streamlitアプリケーションが常に最新のデータを表示することを保証することです。特に、アプリケーションがライブまたは頻繁に更新されるデータを表示している場合には、これが重要です。このチャレンジの解決策は、Streamlitキャッシュにあります。
Streamlitのキャッシュメカニズムにより、アプリはデータをメモリに保存することができるため、アプリが実行されるたびにディスクからロードする必要がありません。
データのロード関数に@st.cache
デコレータを使用することで、アプリケーションの速度と応答性を大幅に向上させることができます。例えば、リモートサーバーからデータを取得する関数がある場合、次のように関数の上に@st.cache
デコレータを追加できます。
@st.cache
def get_data():
# リモートサーバーからデータを取得する
return data
これにより、Streamlitは返されたデータをキャッシュに保存します。関数が再度呼び出されると、Streamlitはまずデータがキャッシュにあるかどうかをチェックします。データがキャッシュに存在する場合、Streamlitは関数を再度呼び出す代わりにキャッシュされたデータを使用します。
さらに、Streamlitはキャッシュされたデータの更新間隔を指定するためにttl
パラメータを提供しています。ttl
を一定の秒数に設定すると、Streamlitはその期間が経過した後に自動的にキャッシュされたデータを更新します。
関数内でttl
パラメータを使用する例を以下に示します。
@st.cache(ttl=60*60*2)
def get_data():
# リモートサーバーからデータを取得する
return data
この例では、ttl
は2時間(60秒×60分×2)に設定されているため、Streamlitは2時間ごとにデータを自動的に更新します。
結論
ポート80でStreamlitアプリケーションを実行することは、特権ポートという性質や使用中のポートや権限など、思わぬ障害があるため、簡単ではありません。しかし、このガイドで議論した洞察力を持っていれば、これらのチャレンジにうまく対処できるはずです。
困難に直面した場合は、どうぞためらわずにStreamlitコミュニティに相談してください。そのコミュニティには、同様の問題に直面した経験豊富な人々がたくさんおり、喜んで助けの手を差し伸べてくれるでしょう。
よくある質問
1. Streamlitアプリケーションをポート80で実行できない理由は何ですか?
Unix系オペレーティングシステムでは、1024以下のポート、ポート80を含むポートは特権とされ、通常はスーパーユーザー(またはルート)アクセスが必要です。必要な権限があるかどうか、およびポートが既に使用されていないかどうかを確認してください。
2. 複数のStreamlitアプリケーションを同時に実行するにはどうすれば良いですか?
--server.port
パラメータを使用して、各アプリケーションに異なるポート番号を指定することで、複数のStreamlitアプリケーションを実行することができます。
3. Streamlitアプリケーションのデータを最新の状態に保つにはどうすれば良いですか?
@st.cache
デコレータをデータのロード関数に使用することで、データをメモリに保存し、アプリケーションの速度と応答性を向上させることができます。また、Streamlitはデータのキャッシュ期間を指定するためにttl
パラメータも提供しています。