【SynologyのNASの活用】ContainerManagerを用いたStreamlitの導入方法

# やりたいこと
Dockerを活用し、SynologyのNAS上にPythonのフレームワーク「Streamlit」でデータのダッシュボードを実現したいが、最新かつ横断的な記事が見つからなかったので自分でやったことをまとめることにした。

# 使用機器・環境
- [DS220+](https://www.amazon.co.jp/gp/product/B087Z6MCKB/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)
    - [メモリ4GB](https://www.amazon.co.jp/gp/product/B07X5MMGWG/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)を増設
        - DS220+の仕様上最大の6GBまで拡張。※資金に余裕があるなら増設を強く推奨。
    - DSM 7.2-64570 Update 1
        - DSM = SynologyのNASの管理システム
    - Container Manager
        - DSMのパッケージセンターからダウンロード可能。[Synologyのナレッジセンター](https://kb.synology.com/ja-jp/DSM/help/ContainerManager/docker_desc?version=7)によれば、Synology用にに最適化されたDockerと理解すれば良いようだ。
- PC
    - Windows 11 Home (Core i7-10870H / 16GB)
    - [Docker Desktop](https://www.docker.com/ja-jp/products/docker-desktop/)
    - [Visual Studio Code](https://code.visualstudio.com/)（以下VSC）
# 大まかな手順
1. 環境構築 (使用機器・環境参照、以降では説明省略)
2. Dockerfileの作成
3. Dockerイメージのビルド
4. Dockerイメージのファイル出力
5. DockerイメージをContainer Managerにインポート
6. コンテナの作成と起動

# Dockerfileの作成
[Shanch blogさんの記事](https://shanch.net/docker-streamlit/)がシンプルでとても分かりやすい。これをベースに、最新のStreamlit公式の情報を反映させた手順は以下の通り。
- まず、VSCにて作業用のフォルダを開く。
    - 作業用のフォルダはどこでも構わない。今回は「Streamlit」というフォルダをデスクトップに作成。
    - フォルダを開く際に「信頼するか？」云々のメッセージが出たらYesでOK。
    <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/4a3c4636-f7de-2a54-7023-d75eac8e4ec8.png">

- 次に、「新しいファイル」をクリックし、「Dockerfile」というファイルを作成。
    <img width = "500" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/429a6407-674d-9f03-a828-5fbd00d817b6.png">
    <img width = "500" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/30c5ecd1-1f22-7206-ac12-c23a183ffd9d.png">

- [Streamlitの公式](https://docs.streamlit.io/knowledge-base/tutorials/deploy/docker#install-docker-engine)から以下のコードをコピペ。
    >FROM python:3.9-slim
    WORKDIR /app
    RUN apt-get update && apt-get install -y \
        build-essential \
        curl \
        software-properties-common \
        git \
        && rm -rf /var/lib/apt/lists/*
    RUN git clone https://github.com/streamlit/streamlit-example.git .
    RUN pip3 install -r requirements.txt
    EXPOSE 8501
    HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
    ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/711f9ea1-8a4c-35cd-5df7-4dc0a1ed888a.png">

# Dockerイメージのビルド
同じく、[Shanch blogさんの記事](https://shanch.net/docker-streamlit/)を参考にする。
- VSCにて作成したDockerfileを右クリックし、Build Imageを選択。
    <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/bbba5f3d-811f-f8c9-b8f6-af1e392ba40d.png">
- イメージ名が自動生成されるので、これで良ければEnterを押下。
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/f3f600d1-f566-67a1-1920-7080ec632fc6.png">
- （参考1）ターミナルに処理の詳細が出力された様子。
    <img width = "400" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/25311ec7-0f4a-020f-2568-53d9e484aacf.png">
- （参考2）Dockerのイメージとしてstreamlitが生成された様子。
    <img width = "400" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/c0552a0b-e781-35c8-1b57-2b3bdba244a8.png">
- （参考3）イメージを起動して任意のブラウザで http://localhost:8501 にアクセスするとStreamlitのデモページが開く。
    <img width = "300" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/a02c77fc-c3c5-e337-21a6-60b50959d255.png">
    <img width = "500" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/835670a3-a49d-dd8b-0c96-55f58de58c6c.png">

# Dockerイメージのファイル出力
VSCのターミナルにて、
docker save -o streamlit.tar streamlit
と入力すると、生成したイメージをファイルとして出力することができる。出力先はコマンドを入力した際のカレントフォルダで、今回はVSCで開いていた作業フォルダ。最終的にstreamlit.tarというファイルが生成される。
    <img width = "500" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/24a5ca05-324f-98c0-6168-a2dd499f1beb.png">
    <img width = "400" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/ca7191cf-a07c-cb78-c7cf-f73bfd47a267.png">

# DockerイメージをContainer Managerにインポート  
以降はDS220+をDSM上で操作していく。
- Container Manager上にてイメージ⇒操作⇒インポート⇒ファイルから追加⇒ローカルデバイスからの順で選択し、ファイル選択画面にて上で生成したstreamlit.tarを選択すると読み込みが始まる。
    <img width = "500" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/9f09277b-5abf-4017-18c4-58e514f0f63a.png">
- 1~2分で読み込みが終わり（通信環境等に依存する可能性有）、イメージ一覧の中にstreamlitが追加される。
    <img width = "700" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/562300bc-827a-8773-38d0-923bdcfd2c39.png">

# コンテナの作成と起動
同じく、Container Manager上で作業を継続する。
- コンテナ⇒作成にて全般設定のウィンドウが開くので、イメージとしてstreamlit:latestを選択する。
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/ccc7cb7c-5f42-a0a4-f36a-cb053a807c96.png">
- お好みのコンテナ名を入力して次へ。
    <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/ff201757-ee81-91d1-ca5f-c3e52c827c8a.png">
- ポートの設定を行う。Streamlitのポート（プログラムを区別する番号みたいなものととらえれば良いか）は標準で8501だが、コンテナに任意のポートの番号を割り当てることができる。例えばここでは1234とすると、コンテナ内部では8501に変換してStreamlitにアクセスできる。なお、このウィンドウの下方にはその他にも設定項目があるが、デフォルトのままで次に進む。
    <img widgh="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/5646770a-99f0-ddce-e0b7-56dd5089410d.png">
- 特に問題が無ければ完了。コンテナが自動で起動する。
    <img width="500" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/548ddec0-badd-de04-115f-077e31decb01.png>

# 動作確認
任意のブラウザにて、DS220+のIPアドレス:ポート番号を入力すると、Streamlitのデモページが開く。例えばIPアドレスが123.456.789.012、ポートが1234の場合、http://123.456.789.012:1234と入力すればよい。
    <img width="500" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752732/ca48b2f1-effc-1d04-cb66-dc63a3b4cd78.png>

# あとがき
細かい説明は省き、とにかくSynologyのNAS上でStreamlitをDockerコンテナで動かしたい、という目的に特化した内容となった。実際にどのようにカスタマイズしていくかは別途記事化していきたい。