IBM Cloud Virtual Server x PodmanでFlowiseを起動するまで

# この記事について
Podmanの事例であまり聞かない、Ubuntu22.04 Server x Podman環境で、生成AIを使ったノーコード/ローコード開発ツール「Flowise」を動かすまでの備忘録です。Ubuntu22.04 Server x Podman環境に慣れておくことで、Raspberry Pi 等のようなエッジサーバー/エッジデバイスにも応用できます。

なお、試行錯誤結果を整理して書いていますが、今後の各ソフトウェアのバージョンアップ次第では、ここで書いていることが使えないことが十分に考えられますのでご注意ください。

# Podman（ポッドマン）を選んだ理由
Podmanは、RedHat社が中心となって開発したコンテナ管理ツールです。ここ数年のIBM Cloudの動きは、RedHat社がIBMとの繋がりが増えたあたりからKubernetesやOpenShiftといったコンテナ関係に集中してアップデートや新機能の追加が増えているため、IBM Cloudを使うことを前提にした場合、ドキュメントの豊富さやOpenShiftとの繋がりからコンテナ管理ツールとしてPodmanを選んでいます。

２つ目にPodmanを使って、KubernetesのYAMLファイルを生成することができるので、パブリッククラウドのみならず、Newオンプレミス（コンテナ等のクラウドコンピューティング技術を適用し、クラウドネイティブ化したオンプレミス環境）に向けたコンテナ活用として、Podmanは取り組みやすいと言えます。
KubernetesのYAMLファイルを作成する際には、なるべく手間を省きたいものです。

３つの理由を挙げるとすれば、インストールが手軽なことでしょう。Dockerのインストールマニュアルをご覧いただくとわかりやすく、より少ない手順でインストールできることは、学習者の心理的ハードルを下げ、トラブルが減ります。

# 今回の使用環境
IBM Cloud Virtual Server for VPC または、IBM Cloud Virtual Server for Classicのどちらかで、サーバーを用意します。

- 開発や検証環境として使う場合：IBM Cloud Virtual Server for Classic の「一時サーバー」を選択
- 本番環境として使う場合：IBM Cloud Virtual Server for VPCを利用。

この記事では、ロケーションは東京、OSにUbuntu 22.04 Server、2つの仮想CPUと8GBのメモリを選択した仮想サーバーになります。

< IBM Cloud Virtual Server for Classic の場合 >
![スクリーンショット 2023-09-12 16.01.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/728c2fa8-fa43-8f8a-682b-52f42fc480a7.png)

< IBM Cloud Virtual Server for VPC の場合 >
![スクリーンショット 2023-09-12 16.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/cbf7441a-6705-ae25-8a3d-e96d3a27ea1e.png)

# Podman環境の構築
作業用ユーザーを作成し、作業用ユーザーを使って、Podmanを実行する環境を整えていきます。以下の順番で作業を進めます。

## 作業用ユーザーの作成
ここでは、rootユーザーしかない状態で、workuser1 というユーザーを作り、管理者権限を付与します。
rootユーザー以外の作業用の管理者権限を持つユーザーが登録されていれば、そちらを使うのも良いでしょう。
SSH接続で、サーバーにアクセスします。次のコマンドを実行します。
```
# adduser workuser1
# usermod -aG sudo workuser1
```
SSH接続からログアウトし、作成した作業用ユーザーを使って、SSH接続し直します。以後、作成した作業用ユーザーで進めます。

## podman インストールの前段の準備
サーバーのタイムゾーンや日本語言語パック、Pythonでpipを使えるようにしておくことも必要です。
```
sudo apt-get update
sudo apt-get upgrade
sudo timedatectl set-timezone Asia/Tokyo
sudo apt-get install curl gcc git make language-pack-ja 
sudo apt-get install python3-pip
```
## podmanおよびpodman-dockerのインストール
Podmanをインストールします。また、Podmanコマンドの代わりに、Dockerコマンドも使えるように、podman-dockerも一緒にインストールしておきます。
```
sudo apt-get install podman
sudo apt-get install podman-docker
```
Ubuntu22.04で、ソースコードからビルドする以外でPodmanをインストールする場合、バージョン 3.4.4 が入ります。
2023年9月現在、aptを使ってインストールしたPodmanで、後述のpodman-composeを使うと「exit code: 125」のエラーが出るため、Podmanを動かしているGo言語のバージョンを下げるため、次のコマンドを実行します。
```
sudo apt install podman=3.4.4+ds1-1ubuntu1 --allow-downgrades
```
### ダウングレード実行前のGo言語のバージョン
```
Version:      3.4.4
API Version:  3.4.4
Go Version:   go1.18.1
Built:        Thu Jan  1 09:00:00 1970
OS/Arch:      linux/amd64
```
### ダウングレード実行後のGo言語のバージョン
```
Version:      3.4.4
API Version:  3.4.4
Go Version:   go1.17.3
Built:        Thu Jan  1 09:00:00 1970
OS/Arch:      linux/amd64
```
Podmanのバージョンに変化はありませんが、Go言語のバージョンが変わっています。Ubuntu 22.04かつPodmanバージョン3.4.4で起きていることですので、今後改善されるはずです。あるいはPodmanをソースコードからビルドしてインストールするかどうか。

# Podman環境で、Docker-Composeを使用可能にする
コンテナを扱う場合、多くのソフトウェアでは、Dokcer-Composeに対応する定義ファイル「docker-compose.yml」が配布されているので、Podman環境でも「docker-compose.yml」を利用できるようにします。
## podman-composeおよびスタンドアローン版docker-composeのインストール
次のコマンドを実行します。
```
pip3 install podman-compose
sudo curl -SL https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```
スタンドアローン版Docker Composeは、2023年9月現在の最新版である、バージョン 2.20.3 を使っています。
https://docs.docker.com/compose/install/standalone/ を見てインストール時に使えるバージョンを確認しましょう。

## Podman APIソケットサービスの起動
Docker-Composeを使えるようにするため、Unixソケット作成を行います。
```
systemctl --user daemon-reload
systemctl --user enable --now podman.socket
```
実行結果(作業用ユーザーが、workuser1の場合）
```
Created symlink /home/workuser1/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket.
```
docker-composeは、DOCKER_HOST経由操作するので、作業用ユーザーの「.profile」に、「DOCKER_HOST=unix://」を追記します。

podman.sockのパスを確認
```
podman info --format '{{.Host.RemoteSocket.Path}}'
```
実行結果例(この結果は、それぞれ異なるので、自分の環境で上記コマンドを必ず実行しましょう。コピペに意味はありません。)
```
/run/user/1001/podman/podman.sock
```
作業用ユーザーの「.profile」に、「DOCKER_HOST=unix://」を追記します。エディタはnanoを使っていますが、vimでも良いです。
```
nano .profile
```
末尾に、下記を追記します。追記後、上書き保存します。
```
export DOCKER_HOST=unix:///run/user/1001/podman/podman.sock
```
export DOCKER_HOST=unix://の後ろは、podman info --format '{{.Host.RemoteSocket.Path}}' の実行結果になります。

保存後、sourceコマンドを使って反映します。
```
source .profile
```

## Ubuntu22.04におけるPodman3.4.4のCNI関係の警告回避方法
Ubuntu22.04で、Podman3.4.4を実行する際に、次のような警告が表示されることがあります。
関連情報 [Ubuntu 22.04.1 LTS libpod (package podman 3.4.4+ds1-1ubuntu1.22.04.1): broken network functionality for CNI plugins](https://bugs.launchpad.net/ubuntu/+source/libpod/+bug/2024394)
```
WARN[0000] Error validating CNI config file /home/あなたのユーザー名/.config/cni/net.d/docker_default.conflist: [plugin bridge does not support config version "1.0.0" plugin portmap does not support config version "1.0.0" plugin firewall does not support config version "1.0.0" plugin tuning does not support config version "1.0.0"] 
```
対処方法として、「containernetworking-plugins」を、インストールすることで解決できる。
```
curl -O http://archive.ubuntu.com/ubuntu/pool/universe/g/golang-github-containernetworking-plugins/containernetworking-plugins_1.1.1+ds1-1_amd64.deb
sudo dpkg -i containernetworking-plugins_1.1.1+ds1-1_amd64.deb
```

# Flowise
Flowiseは、大規模言語モデル（LLM）を用いたアプリケーションを作るための開発ツールで、Webブラウザ上で使うノーコード/ローコードツールです。
Webサイト：https://flowiseai.com/

この章では、構築したPodman環境でFlowiseを動かすまでを説明します。
## Gitからダウンロード
FlowiseのGitリポジトリから、ソースコードを取得します。
```
git clone https://github.com/FlowiseAI/Flowise.git
cd Flowise/docker
ls -l
```
ダウンロードしたFlowiseのdockerディレクトリには、次のファイルが格納されています。(作業用ユーザー名が、workuser1の場合)
```
-rw-rw-r-- 1 workuser1 workuser1  721 Sep 12 13:08 .env.example
-rw-rw-r-- 1 workuser1 workuser1  441 Sep 12 13:08 Dockerfile
-rw-rw-r-- 1 workuser1 workuser1 1309 Sep 12 13:08 README.md
-rw-rw-r-- 1 workuser1 workuser1  686 Sep 12 13:27 docker-compose.yml
```
### docker-compose.ymlの編集
Podman環境で、docker-compose.ymlを使うために、docker-compose.ymlを編集します。
編集には、nanoエディタを使っていますが、vimでも構いません。編集後、上書き保存します。
```
nano docker-compose.yml
```
編集前
```
image: flowiseai/flowise
```
編集後
```
image: docker.io/flowiseai/flowise
```
これで、docker hubに公開されている、Flowiseのコンテナイメージを取得できるようになります。
### .envファイルの複製と編集
.envファイルを、.env.exampleから複製します。
```
cp .env.example .env
```
編集には、nanoエディタを使っていますが、vimでも構いません。編集後、上書き保存します。
```
nano .env
```
編集前
```
PORT=3000
PASSPHRASE=MYPASSPHRASE # Passphrase used to create encryption key
DATABASE_PATH=/root/.flowise
APIKEY_PATH=/root/.flowise
SECRETKEY_PATH=/root/.flowise
LOG_PATH=/root/.flowise/logs
```
編集後
```
PORT=3000
PASSPHRASE=MYPASSPHRASE # Passphrase used to create encryption key
DATABASE_PATH=/root/.flowise
APIKEY_PATH=/root/.flowise
SECRETKEY_PATH=/root/.flowise
LOG_PATH=/root/.flowise/logs
FLOWISE_USERNAME=adminuser
FLOWISE_PASSWORD=admin1234admin
```
「FLOWISE_USERNAME」と「FLOWISE_PASSWORD」を追加し、Flowiseの作業画面に認証機能を追加しました。環境変数は他にもあるので、詳しくは以下を確認すると良いでしょう。
https://github.com/FlowiseAI/Flowise/blob/main/CONTRIBUTING.md#-env-variables

#### Podman環境で、Flowiseをまっさらな状態から起動し直すような場合
「DATABASE_PATH」、「APIKEY_PATH」、「SECRETKEY_PATH」は、rootディレクトリ下の自動作成される「.flowise」となり、ログは、「.flowise」下の「logs」になっています。
もし、Podman環境で、Flowiseをまっさらな状態から起動し直すような場合は、rootディレクトリ下の自動作成される「.flowise」ディレクトリを削除してから、Flowiseを起動しましょう。

### Flowiseの起動
Podman環境で、docker-compose.ymlを使って、Flowiseを起動します。
```
podman-compose -f docker-compose.yml up -d
```
実行結果
```
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 3.4.4
** excluding:  set()
['podman', 'ps', '--filter', 'label=io.podman.compose.project=docker', '-a', '--format', '{{ index .Labels "io.podman.compose.config-hash"}}']
['podman', 'network', 'exists', 'docker_default']
['podman', 'network', 'create', '--label', 'io.podman.compose.project=docker', '--label', 'com.docker.compose.project=docker', 'docker_default']
['podman', 'network', 'exists', 'docker_default']
podman run --name=docker_flowise_1 -d --label io.podman.compose.config-hash=617a2761390ef7fb87c75b4f759ba82e3f0bc7ad247aeca8815929dd450404e0 --label io.podman.compose.project=docker --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@docker.service --label com.docker.compose.project=docker --label com.docker.compose.project.working_dir=/home/workuser1/Flowise/docker --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=flowise -e PORT=3000 -e PASSPHRASE=MYPASSPHRASE -e FLOWISE_USERNAME=adminuser -e FLOWISE_PASSWORD=admin1234admin -e DEBUG= -e DATABASE_PATH=/root/.flowise -e APIKEY_PATH=/root/.flowise -e SECRETKEY_PATH=/root/.flowise -e LOG_LEVEL= -e LOG_PATH=/root/.flowise/logs -v /home/workuser1/.flowise:/root/.flowise --net docker_default --network-alias flowise -p 3000:3000 --restart always docker.io/flowiseai/flowise /bin/sh -c sleep 3; flowise start
Trying to pull docker.io/flowiseai/flowise:latest...
Getting image source signatures
Copying blob 751194035c36 done  
Copying blob 7264a8db6415 done  
Copying blob eff5dce73b38 done  
Copying blob c8ce5be43019 [======================================] 447.0b / 447.0b
Copying blob 253e3c6f8f4f done  
Copying blob e9a82e626ce4 done  
Copying blob 3a80f4d63265 [======================================] 21.8MiB / 21.8MiB
Copying blob dcea9fb00269 done  
Copying blob fee78030adc2 done  
Copying blob 89aa40859ec2 [======================================] 94.0b / 94.0b
Copying config 4a72673c7a done  
Writing manifest to image destination
Storing signatures
1e49e09c3b14b4c9bee4071879642ecdd3008c1e9778704cbed180d45e9511a9
exit code: 0
```
Podmanのコンテナ起動状況を確認します。
```
podman ps -a
```
実行結果
```
CONTAINER ID  IMAGE                               COMMAND               CREATED             STATUS                 PORTS                   NAMES
1e49e09c3b14  docker.io/flowiseai/flowise:latest  /bin/sh -c sleep ...  About a minute ago  Up About a minute ago  0.0.0.0:3000->3000/tcp  docker_flowise_1
```
もし、コンテナが停止した場合は、「podman start コンテナID」を実行することで、再びコンテナが動きます。この辺りは、dockerコマンドとほぼほぼ同じです。

# Webブラウザで確認
Webブラウザで、http://Podmanを実行しているサーバーのIPアドレス:3000 にアクセスします。IPアドレスの代わりに、FQDN(ホスト名+ドメイン名)の方が良いですが、独自ドメインが必要なので、本格的に運用する時までに独自ドメインを取得しておきましょう。
![スクリーンショット 2023-09-12 17.17.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/c6dec262-a5d3-4912-f58f-eb7eb83d283c.png)

Login画面で、.envファイルで設定した「FLOWISE_USERNAME」と「FLOWISE_PASSWORD」の値を入れ、「Login」をクリックします。
作業画面が利用可能になります。
![スクリーンショット 2023-09-12 17.19.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/6ebe0634-5226-8299-8104-c76845b7c35c.png)
画面左側の「Marketplaces」をクリックすることで「Chatflow」タブには、いくつかのLLMを前提としたアプリケーションを作るための雛形（テンプレート）を確認することができます。
![スクリーンショット 2023-09-12 17.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/f9515fad-80d9-555c-8d4b-4374c52ac399.png)
テンプレート名をクリックすると詳細が表示されます。
![スクリーンショット 2023-09-12 17.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/72f86064-bacf-cba4-98b6-e0c052cf7f43.png)
画面右上の「Use Templace」をクリックすることで、テンプレートを使って、LLMアプリケーションの開発をスタートすることができます。
![スクリーンショット 2023-09-12 17.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41414/bb3aac90-0e96-571e-f53e-89fd6264c750.png)

# まとめ
2023年9月現在、Flowiseの公式ドキュメントには、IBM Cloudで動かす手順というものがありません。
https://docs.flowiseai.com/deployment
そこで、今回は、IBM Cloudを使い、Dockerではなく、PodmanでFlowiseを動かす手順を書くことにしました。Ubuntuを使っていますので、Rasberry Pi等のシングルボードコンピュータを用いたエッジサーバー/エッジデバイスにも応用することができます。

# 参考資料
Flowiseのドキュメント:https://docs.flowiseai.com/
YouTubeでFlowiseを使ってLLMアプリケーションを作ることを扱った動画：https://www.youtube.com/hashtag/flowise