【macOS】IBM Cloud Virtual Server for VPCにGradioアプリケーションをデプロイする

# はじめに
今回は、IBM Cloud のサービスである [IBM Cloud Virtual Server for VPC](https://cloud.ibm.com/infrastructure/provision/vs) の上にGradio で作成したWeb アプリケーションをデプロイする手順を備忘録として記事にアウトプットします。

IBM Cloud Virtual Server for VPC は[IBM TechZone](https://www.ibm.com/jp-ja/case-studies/ibm-techzone) で払い出しています。

# 環境
* OS : macOS
* 払い出した環境：https://techzone.ibm.com/my/reservations/create/6348390d3eaf9000179fb28b
    * DIY unformatted secondary disk size : 100GB
    * VM Profile : 2vCPU | 8GiB
![techzone1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/e7c90fbf-906a-4a3a-aecf-c4710e405443.png)

# 手順
* [Virtual Server にアクセス](#virtual-server-にアクセス)
* [Python3.12 をインストール](#python312-をインストール)
* [pipをインストール](#pip-をインストール)
* [Web アプリケーションを配置](#web-アプリケーションを配置)
* [Web アプリケーションを実行](#web-アプリケーションを実行)
* [リンクを他の人に配布する](#リンクを他の人に配布する)



# Virtual Server にアクセス
ローカルのVSCode のターミナルでVirtual Server にアクセスします。

1. TechZone の環境詳細にある`Download SSH key` から証明書をダウンロードする
![techzone2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/337d7d5f-f8f7-4b9b-bbe8-a3f00fd5b3dd.png)

1. 証明書をターミナルで実行するディレクトリに配置する

1. ターミナルで以下のコマンドを実行してアクセス権限を設定する
    ``` :ターミナル
    chmod 600 <証明書のファイル名>
    ```
1. VSCode を立ち上げる

1. VSCode の拡張機能、`Remote - SSH` をインストールする
![vscode9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/4f505518-3501-92f5-ab45-f32f80f25632.png)

1. 左下の>< マークをクリックする
![vscode10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/f562aa9b-b578-42ce-afa6-f92e32660bfe.png)

1. `ホストに接続する…` をクリックする
![vscode11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/7b757ee2-7e16-4bd7-b09a-8c4a4279f098.png)

1. `+新規SSH ホストを追加する…` をクリックする
![vscode12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/0dac14b7-4519-4968-989d-e99a40798d67.png)

1. `ssh itzuser@<PublicIP> -p <SSHPort> -i ~/<証明書のファイル名>` を入力してEnter Key をクリックする
![vscode13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/cac564af-9ad8-4626-b397-bd2491cf19dc.png)

1. `/User/<ディレクトリ名>/.ssh/config` をクリックする（任意のディレクトリを選択できます）
![vscode14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/d60c183f-4079-426f-93bd-b315621feed6.png)

1. 「接続」をクリックする
![vscode15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/6b758f7a-ebff-4c86-ae6b-f74bda0dfea1.png)

1. 完了
![vscode16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/a3c7c205-526a-4359-9f80-a7ede5e31280.png)


# Python3.12 をインストール
ターミナルを立ち上げる。
1. システムを更新する
    ```:ターミナル
    sudo apt update && sudo apt upgrade -y
    ```

1. 必要なパッケージをインストールする
    ```:ターミナル
    sudo apt install -y software-properties-common
    ```

1. deadsnakes PPA を追加する
    ```:ターミナル
    sudo add-apt-repository ppa:deadsnakes/ppa -y
    sudo apt update
    ```

1. Python 3.12 をインストールする
    ```:ターミナル
    sudo apt install -y python3.12
    ```

1. バージョンの確認
    ```:ターミナル
    python3.12 --version
    ```


# pip をインストール
以下を実行して、pip をインストールする
```:ターミナル
sudo apt install -y python3.12-venv python3.12-dev python3-pip
```


# Web アプリケーションを配置

1. VSCode 上で新規フォルダーを作成する

![vscode17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/e31b54d2-86d7-4b26-afe2-831141ffe998.png)

1. ターミナルを起動する
![vscode18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/0f1600b5-24c7-4c91-a5c3-b7fdd88d816f.png)

1. 以下を実行して、作成したフォルダに移動する
    ```:ターミナル
    cd gradio
    ```

1. ローカルにあるWeb アプリケーションファイルをドラッグ&ドロップで配置する
![vscode19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/184b20fe-e0e3-4272-8715-fe6ec77181b3.png)

    ::: note info
    `app.py` の中身はこちら

    ```Python:app.py
    import random
    import gradio as gr
    
    def get_foturne(your_name):
        fortune_lists = ['大吉', '吉', '小吉', '凶', '末吉']
        fortune_result = random.choice(fortune_lists)
        return your_name + "さんの今日の運勢は・・・" + fortune_result + "です"
    
    demo = gr.Interface(fn=get_foturne,
                        inputs="text",
                        outputs="text")
    demo.launch()
    ```
:::

# Web アプリケーションを実行

## gradio のパッケージをインストールする
1.  以下を実行して、gradio をインストールする
    ```:ターミナル
    pip install gradio
    ```

1. 以下を実行して、gradio がインストールされたか確認
    ```:ターミナル
    pip show gradio
    ```
    以下のような出力であればOK
    ```:出力
    Name: gradio
    Version: 5.20.1
    Summary: Python library for easily interacting with trained machine learning models
    Home-page: 
    Author: 
    Author-email: Abubakar Abid <gradio-team@huggingface.co>, Ali Abid <gradio-team@huggingface.co>, Ali Abdalla <gradio-team@huggingface.co>, Dawood Khan <gradio-team@huggingface.co>, Ahsen Khaliq <gradio-team@huggingface.co>, Pete Allen <gradio-team@huggingface.co>, Ömer Faruk Özdemir <gradio-team@huggingface.co>, Freddy A Boulton <gradio-team@huggingface.co>, Hannah Blair <gradio-team@huggingface.co>
    License: 
    Location: /home/itzuser/.local/lib/python3.10/site-packages
    Requires: aiofiles, anyio, fastapi, ffmpy, gradio-client, groovy, httpx, huggingface-hub, jinja2, markupsafe, numpy, orjson, packaging, pandas, pillow, pydantic, pydub, python-multipart, pyyaml, ruff, safehttpx, semantic-version, starlette, tomlkit, typer, typing-extensions, uvicorn
    Required-by:
    ```

## 起動
```:ターミナル
python3 test.py
```
![vscode20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/e0717670-8f27-484c-b846-53441aee928e.png)

上のように、URLが発行されればOK！

リンクを開いてみると…
![vscode21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/f70e8056-ab62-4a31-9837-beded5d05cf6.png)


# リンクを他の人に配布する
Virtual Server にデプロイしたWeb アプリケーションのリンクを他の人に共有するための手順です。
1. `demo.launch()` の`()` の中でサーバーとポートの指定をする
    ```Python:app.pyの最終行
    demo.launch(server_name="0.0.0.0", server_port=8080)
    #開いていることが確認できた8080を指定
    ```

1. 起動
    ```:ターミナル
    python3 test.py
    ```
    ![vscode22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/e9008744-14b1-48d3-8228-eff23cd23857.png)

1. `http://<PublicIP>:8080/` をブラウザで開く
![vscode23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851617/ff46f1f8-c6af-4125-bb7a-5c885789174a.png)