Streamlit PythonをIBM Cloudへデプロイするよ


手軽にPythonにUIを追加してアプリケーションを作成できるStremlitを使い始めています。ローカルで実行できるので開発やテストは問題ないのですが、できあがったアプリを他の人に見てもらうにはどこかにデプロイする必要があります。
Stremlitでは[StremlitSharing](https://streamlit.io/cloud)というStremlitの専用の公開サイトがあるのでそこへ手軽にデプロイできるのですが、他のデプロイ先も試してみようと思います。
Herokuとかへのデプロイする情報が多いのですが、今回はあまり情報のないIBM Cloud Code Engineへのデプロイを試してみました。

## 事前チェック
下記のものを準備しておいてください。
* IBM Cloud アカウント (ライトアカウント以上）
* GitHub アカウント
* Git CLI

## IBM Cloud
[IBMのクラウドサイト](https://www.ibm.com/jp-ja/cloud)です。企業向けに力を入れてる感じです。開発したアプリケーションをデプロイする方法としてはいろいろあるのですが、昨年2021年に、Code Engineというサーバーレスランタイム環境が正式公開されたのでこちらを試してみます。

## Code Engine
[IBM Cloud Code Engine](https://www.ibm.com/jp-ja/cloud/code-engine)
サーバーレスのコンテナ、アプリケーションコード、バッチを実行できる環境として提供されています。開発者がサーバーとかインフラとか意識せずにアプリケーションを公開できる環境として便利ですね。

ここにアプリケーションをデプロイする方法としてはあらかじめDockerイメージを作成する方法とGithubに配置したソース・ファイルを元にしてDockerイメージを作成してデプロイする方法があります。（HerokuとかStremlitSharingと同じような使い方というとGithubソースの方なのでこちらをやってみます。）
## Github準備
### サンプルソースの準備
作成したソース・ファイルをGithubで公開します。参照してください。
https://github.com/saboten10/simple_streamlit

必要なものは下記の３つのファイルになります。
* python program file
* Dockerfile
* requirement.txt

### Dockerfileの説明
IBM Cloude Code Engineへデプロイするのに必要となるDockerfileになります。Dockerイメージファイルのサイズが気になる人はSlimも利用できます。

```Dockerfile:Dockerfile
# For more information, please refer to https://aka.ms/vscode-docker-python
# you can reduce the docker image size by using python:3.x-slim-buster
#FROM python:3.8
FROM python:3.8-slim-buster

# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE=1

# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1

# for python:fullpackage
RUN apt-get update && apt-get upgrade -y

WORKDIR /app

# Exposing default port for streamlit
EXPOSE 8501

# Install requirements
COPY requirements.txt .
RUN pip install -r requirements.txt
#RUN python -m pip install -r requirements.txt

# Copy necessary files
COPY . /app

# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser

# Launch app when container is run
CMD streamlit run sample1.py
```

## Code Engine準備
IBM Cloud上の操作方法を順を追って説明します。
### Code Engineのアクティベート
IBM Cloudのカタログの中のCotainerの中にCode Engineがあります。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/ddeadd44-0198-3fcb-8999-a27285f912f4.png">

## デプロイ操作
Githubにアップロードされているソースコードを元にIBM Cloud Code Engineへデプロイする方法を最初から手順を順番にやっていきます。
### ソース・コードから始める
Code EngineのスタートページにDockerイメージから始めるか、ソースコードから始めるか選ぶところがあるのでソースコードを選択してください。
ソースコードリポジトリには自分のGithubのソースコードリポジトリを指定します。自分のはパブリックにしていますが非公開でも対応できます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/806ace94-52a9-e5b5-9614-ec5893f83bd3.png">
ソースコードリポジトリに自分のGithubを指定して、「作成の開始」ボタンを押します。

### 作成の開始
なんか翻訳が変なのかな、日本語的におかしな感じがしますが作成するアプリケーションの情報を入れていきます。
上から順番に指定していきます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/492288ce-a080-9c85-dc6b-cc19b2f0d444.png">

アプリケーション名:simple-streamlit-application-20220130
としておきます。アンダーバーが使えないので注意してください。
プロジェクトの作成ボタンを押すと画面の右側に次のような画面が出てきます。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/41c13c81-bd48-b292-58ea-2b4468d6500c.png">

### アプリケーションの作成
なんかプロジェクトがロードできないとかエラーが出たのでCode Engineのメニューから作成したプロジェクトを選択してアプリケーションの作成を選択
※本当はこのまま進めるはずです。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/db92b87a-bb9a-7fca-72a9-4b858c511509.png">


赤枠部分を入力して、「ビルド詳細の指定」ボタンを押す。
ビルド詳細の指定画面が出てくるのでブランチ名を「master」として「次」へ

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/1ecd4478-09ae-6739-88d2-dd46b1f8a05c.png">


その後はディフォルトのまま進むと作成するDockerイメージを格納するリポジトリが作成されて元の画面に戻ります。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/1e73cde3-f4a4-96fc-e5b7-6f43237e7be3.png">


### ビルドとデプロイの実行

いよいよ「作成」ボタンを押します。
イメージビルドから始まって、成功すると自動的に環境へデプロイまで進みます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/ef165c88-e121-d727-3777-13aee362ce43.png">


「準備完了」が表示されるとデプロイが完了してアプリケーションの準備ができました。

### アプリケーションの実行
アプリケーションのテストを押して、「アプリケーションのURL」を押すと対象のURLへアクセスされます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/acf254b3-492f-7662-6834-c1d3e36fb8b6.png">

はい、作成したStreamlitアプリケーションが表示されました！！
おつかれさまでした。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89268/d28c38df-ec95-276b-1dfc-42df99ed91f9.png">

これでアプリケーションをデプロイする環境ができたので、もとのGithub側を変更してビルド、デプロイすればアプリケーションを変更することもできます。
今回のサンプルはStreamlitのタイトルとマークダウンしか出力していないシンプルなプログラムですがベースはできましたので自分のコードで試してみてください。

## お金の話
IBM Cloud Code　Engineはクレジットカードを登録したライトアカウント以上で利用できます。
[費用のページ](https://www.ibm.com/jp-ja/cloud/code-engine/pricing)に詳細が書かれていますが、
* 作成したDockerイメージを格納するレジストリが512MBまでは無料ですが、それ以上だと無料プランからアップグレードする必要があります。この場合は超過した容量が有料（今回のサンプルは273MBなので無料枠です）
* 同じくレジストリからPULLする容量にも制限があります。月間5GB以内が無料枠、それ以上は同じくアップグレードが必要（従量課金）
* 作成したアプリケーションについてもヒット数によって課金です。月間で10万アクセスなのでテストプログラムとかならまぁ大丈夫かな。

実際、今回のDockerファイルではslimイメージを指定しているけど、普通にStreamlitでイメージ作ったら512MBを超えちゃってる。
はみ出した費用はわずかだけど完全に無料でやりたいよね。

## 終わりに
今回はPythonで手軽にUIを作成できるStremlitをIBM Cloudへデプロイする方法について書きました。
* Streamlit Sharing (Streamlit Cloud)
* Heroku
* IBM Cloud

とデプロイを試してきましたがStremlit SharingはStremlitを使ったアプリのみが対象でGithub側のソースはパブリック公開しておかないといけないです。それに対してHeroku、IBM CloudはStremlit以外でも大丈夫ですし、ソースコードもパブリック公開する必要はないのでソースを公開したくない人には選択肢としていいと思います。

特にIBM Cloudには他にもたくさんのサービスがあるのでそれを利用したPythonアプリケーションを作成するのであれば今回のIBM Cloud Code Engineにデプロイするメリットはあると思います。
（もちろんIBM Cloud Code EngineからAzureとかGoogleとか他のAPIも呼び出すことはできます。）