物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Ubuntu (raspberry pi) で streamlit サーバーを作る

手元に好きに使える raspberry pi があったので、立ち上げてみた

サーバー環境の準備

サーバーの選定

環境は以下の通り

$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

必要なパッケージのインストール

sudo apt update
sudo apt install python3 python3-pip python3-venv

Streamlit のセットアップ

仮想環境を作成

python3 -m venv venv
source venv/bin/activate

終わるときは deactivate

Streamlit をインストール

pip install --upgrade pip
pip install streamlit

Streamlit アプリの作成

例えば app.py を適当なディレクトリで作成

import streamlit as st

st.title("Hello Streamlit")
st.write("これはシンプルなStreamlitアプリです。")

Webサーバーとして動作させる

設定ファイルの作成

以下の内容を ~/.streamlit/config.toml に記述。デプロイする場合に使われるだけなので今回は作らなくても良い。

[server]
headless = true
enableXsrfProtection = false
enableCORS = false
port = 8501

アプリを起動

streamlit run app.py

http://localhost:8501 でアクセス可能であることを確認する。

永続化と自動起動設定

nohup でバックグラウンド実行

run.sh を作成し、実行権限を付与。

nohup streamlit run app.py > output.log 2>&1 &

systemd を利用

/etc/systemd/system/streamlit.service を作成

[Unit]
Description=Streamlit App
After=network.target

[Service]
User=physics  # 実行ユーザーに変更
WorkingDirectory=/home/physics/app  # アプリのディレクトリ
ExecStart=/home/physics/.pyenv/venv/bin/streamlit run app.py
Restart=always

[Install]
WantedBy=multi-user.target

起動

sudo systemctl daemon-reload
sudo systemctl enable streamlit
sudo systemctl start streamlit

セキュリティ強化

ufwをインストール、SSH用の22番を開けてから、有効化する

sudo apt install ufw
sudo ufw allow 22/tcp
sudo ufw enable

8501番のまま公開する場合は

sudo ufw allow 8501/tcp

設定確認のためには

sudo ufw status verbose
 $ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere                  
8501/tcp                   ALLOW IN    Anywhere                  
22/tcp (v6)                ALLOW IN    Anywhere (v6)             
8501/tcp (v6)              ALLOW IN    Anywhere (v6)  

Nginx でリバースプロキシ設定

ここからは、chatgptの出力のまま未テスト

ポート 8501 ではなく 80 (HTTP) や 443 (HTTPS) で公開したい場合

Nginxをインストール

sudo apt install nginx

設定ファイル作成

/etc/nginx/sites-available/streamlit を作成

server {
    listen 80;
    server_name raspi10;  # ドメインまたはIP

    location / {
        proxy_pass http://localhost:8501;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

設定適用

sudo ln -s /etc/nginx/sites-available/streamlit /etc/nginx/sites-enabled/
sudo systemctl restart nginx

HTTPS化する場合は certbot を利用

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d raspi10