Streamlitで作成したアプリを高火力DOKの外部接続機能で使ってみた

## はじめに
株式会社晴工雨読の片山と申します。晴工雨読の概要はこちらからご覧ください。

https://seikoudoku.co.jp/

Techブログ第3弾は、Streamlitで作成したアプリをさくらインターネットの高火力DOKに搭載された外部接続機能で利用する方法を解説していきます。まずそれぞれのツールの概要を、その後実際の手順をハンズオン形式で述べていきます。

## Streamlitとは
Streamlitは、簡単にインタラクティブなウェブアプリケーションを構築して、データサイエンスや機械学習プロジェクトを可視化したり、その結果を共有したりできる、お役立ちツール(ライブラリ)です。

https://docs.streamlit.io/

今回は、最近流行ってきている(？)、探索的データ解析(EDA)やデータの可視化を効率的に行えるPyGWalkerと組み合わせて使います。

## 高火力DOK(ドック)とは
高火力DOKは、さくらインターネットが提供するコンテナサービスです。高性能GPUが従量課金制かつ比較的低価格で利用できる点が特徴のようです。今回はこのサービスを利用していきます。

https://www.sakura.ad.jp/koukaryoku-dok/

## 実行手順
### 1. Dockerイメージを作成
任意のディレクトリの中に3つのファイルを配置し、Dockerコマンドを利用して実行確認します。今回はpygwalker-appディレクトリと命名したディレクトリにファイルを配置しました。まずは、それぞれのファイルの内容を解説していきます。

```text:directory
pygwalker-app
├─ Dockerfile
├─ requirements.txt
└─ app.py
```

今回は、DockerイメージをDockerfileで作成することにしました。ここはファイル内のコメントに解説を記しています。

```Dockerfile:Dockerfile
# ベースイメージとしてPython 3.9を使用
FROM python:3.9

# 作業ディレクトリを作成
WORKDIR /app

# ローカルのPythonファイルとrequirements.txtをコンテナ内にコピー
COPY ./app.py /app/
COPY ./requirements.txt /app/

# 必要なパッケージをインストール
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8501

# デフォルトの実行コマンド
ENTRYPOINT ["streamlit", "run"]
CMD ["app.py"]
```

コンテナに作成されるPython環境の中に、必要なパッケージ(ライブラリ)を入れていくための環境情報ファイルを作成します。今回はStreamlitとPyGWalkerを利用するのに必要なパッケージをインストールします。

```text:requirements.txt
streamlit==1.40.1
pygwalker==0.4.9.13
```

実行するPythonファイルは、[PyGWalkerとStreamlitを使ったデータの探索と情報共有](https://docs.kanaries.net/ja/pygwalker/use-pygwalker-with-streamlit)を参考に、StreamlitでPyGWalkerを利用するアプリケーションを記述します。今回はプログラムの中にデータを埋め込んでいますが、アプリを立ち上げた後にブラウザからデータを入力することももちろん可能です。

```python:app.py
from pygwalker.api.streamlit import StreamlitRenderer
import pandas as pd
import streamlit as st
 
# Adjust the width of the Streamlit page
st.set_page_config(
    page_title="Use Pygwalker In Streamlit",
    layout="wide"
)
# Import your data
df = pd.read_csv("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/public-datasets/bike_sharing_dc.csv")
 
pyg_app = StreamlitRenderer(df)
pyg_app.explorer()
```

### 2. ローカル環境で実行確認
ファイルを配置したディレクトリに入り、Dockerコマンドを利用して実行確認します。1行目でイメージを作成し、それを利用して2行目でコンテナを起動します。確認される画面は、手順4で確認する画面と同様なので、ここでは割愛します。

```terminal:bash
$ docker build -t myapp:latest . 
$ docker run myapp
```

### 3. Docker Hubへイメージをアップロード
ローカルでの実行確認が完了したので、Docker Hubへイメージをアップロードして高火力DOKで実行する準備をしていきます。

ローカル環境にて実行確認した時と同じ階層で、まずDocker(Docker Hub)にログイン後、イメージをビルドし、タグづけ、そしてプッシュを行います。`yourusername`にはユーザ名を、`yourimagename`には任意のイメージ名を入れてください。

```terminal:bash
$ docker login
$ docker buildx create --use
$ docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/yourimagename:latest --push .
```

`docker buildx`コマンドについて補足ですが、今回はマルチプラットフォームイメージというものを作成しています。これは私のデバイスがMacbookであることから、そのほかの環境でも正常に起動するためです。詳細な内容は参考文献からご確認ください。

ここまでの工程を経て作成したイメージは一般公開していますので、これまでの手順を踏まずに次の手順から試すことも可能です。

https://hub.docker.com/repository/docker/shikettahinachan/streamlit-dok-blog/general

### 4. 高火力DOKでDockerイメージを実行
ではいよいよ、高火力DOKでDockerイメージを実行していきます。基本的には、[WandBとさくらインターネットの高火力DOKを組み合わせて使ってみた](https://qiita.com/hinatakatayama/items/f60656de7ef3a4eea998)と同様の流れで進みます。

ログイン後、「タスク」タブから「新規作成」を選択し、イメージに前の手順でアップロードしたイメージのイメージ名とタグを入れます。「環境変数」には[外部からの接続方法｜さくらのクラウド](https://manual.sakura.ad.jp/cloud/koukaryoku-container/listening-port.html)も参照して任意のトークンを設定しましょう(画像内「authorized-token」部分)。

外部接続機能を利用するにあたって最大のポイントは、HTTPボタンをオンにして、「ポート」に適切なポート番号を設定することです。今回は8501番を設定しています。

![タスク作成画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/7279051f-c4ea-8334-c3e4-5f33d7d59a7e.png)

この画面で「作成」を押すと、実行が開始されます。「HTTP URI」部分のテキストをコピーし、末尾に設定したトークンを`/?token=authorized-token`のように追記したURLにアクセスすると、Streamlitで作成されたアプリを見ることができます。

![実行結果画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900397/201544c5-2124-22a4-8083-84fe25f235a7.png)

この画面から、探索的データ解析(EDA)やデータの可視化を効率的に行えそうですね。（終了後は、タスクを中断するのをお忘れなく。）

## おわりに
今回は、Streamlitで作成したアプリをさくらインターネットの高火力DOKに搭載された外部接続機能で使ってみました。ローカルのスペックや環境とは関係なく、ブラウザで一時的な分析を進められるのはとてもありがたいですね。

## 参考文献
- [DockerでStreamlitのwebアプリを動かす](https://zenn.dev/kthrlab_blog/articles/2250b74ec16206)
- [Docker Buildx](https://matsuand.github.io/docs.docker.jp.onthefly/buildx/working-with-buildx/)
- [docker-buildxとmulti-platform build周りについてまとめ](https://zenn.dev/bells17/articles/docker-buildx)
- [常駐するタイプのタスクを実行できますか？｜さくらのクラウド](https://manual.sakura.ad.jp/cloud/koukaryoku-container/faqs.html#id14)