M1 Mac上でcolimaを使ってDb2 Community Edition Docker イメージを動かす

M1 Macに会社のPCが変わりました。以前はIntel MacでDocker Desktopは会社的に有償になったので、podman を入れてdockerでなんちゃらという場合はpodmanでコマンドベースでやっていました。
M1 Macでもpodmanかと思ったら、Db2 Community Edition Docker イメージはうまく動きませんでした。
紆余曲折の末、colimaでバッチリ動く方法が確認できましたので、その方法です。


参考: 
- colima: https://github.com/abiosoft/colima
- Db2 Community Edition for Docker: https://www.ibm.com/docs/ja/db2/11.5?topic=deployments-db2-community-edition-docker

# 1. まずはcolimaとdockerをサクッとインストール

よくわかってなかったのですが、colimaにはdockerが必要らしいです。
mac版のdocker Desktopじゃなくてdockerがあるのか！！！とこの時思いました。え、じゃあdockerだけでよくない？と考えたのですが、これはarm64アーキテクチャのdockerらしく(?)、amd64版しかないDb2 Community Edition Docker イメージは動きませんでした。
いろいろ調べた結果colima+dockerでamd64版のdockerイメージをサクッと動かす環境ができるとのことでした。

## colimaとdockerの導入
```
brew install colima docker
```

導入は簡単でした!

# 2. colimaの起動
amd64版しかないDb2 Community Edition Dockerイメージを動作させるので、
`--arch x86_64`
オプションをつけて起動します。

macOS v13以上の場合(なんかこの方が速いらしいです):
```
colima start --arch x86_64 --vm-type vz --vz-rosetta --mount-type virtiofs
```

macOS v13未満の場合:
```
colima start --arch x86_64 --runtime docker
```

起動例:
```
~:$ colima start --arch x86_64 --vm-type vz --vz-rosetta --mount-type virtiofs
INFO[0000] starting colima
INFO[0000] runtime: docker
INFO[0000] preparing network ...                         context=vm
INFO[0000] creating and starting ...                     context=vm
INFO[0052] provisioning ...                              context=docker
INFO[0052] starting ...                                  context=docker
INFO[0059] done
~:$
```



ちなみにcolimaの停止は以下のコマンドです。
```
colima stop
```

colimaが起動してるかどうかわからないときは以下のコマンドでStatusをみましょう。
```
colima status
```


# 3. ICR(IBM Cloud Registry) から Db2 Dockerイメージをpull
以前はdocker hubからpullしたのですが、今はICR(IBM Cloud Registry)からpullするようになりました。
また先にpullしなくても起動時になければpullしてくれますが、ここは[ドキュメントのプロシージャーのStep3の通り](https://www.ibm.com/docs/ja/db2/11.5?topic=system-macos#taskt_install_db2CE_img__steps__1)先にpullしておきます。
```
docker pull icr.io/db2_community/db2
```
ちなみに結構時間かかりました。10-15分???
サイズが2.84GBでした！
```
~:$ docker images
REPOSITORY                 TAG       IMAGE ID       CREATED       SIZE
icr.io/db2_community/db2   latest    7beff879b820   5 weeks ago   2.84GB
```


# 4. Db2 Dockerイメージの起動
[ドキュメントのプロシージャーのStep5](https://www.ibm.com/docs/ja/db2/11.5?topic=system-macos#taskt_install_db2CE_img__steps__1)では環境変数ファイルを作成していますが、ここでは最低限起動するレベルの環境変数を指定します。
環境変数の詳細は[ドキュメントのプロシージャーのStep5](https://www.ibm.com/docs/ja/db2/11.5?topic=system-macos#taskt_install_db2CE_img__steps__1)を参照してみてください。

最初にインスタンスのパスワードを決めてください。
ここでは `Passw0rd`としました。
 

以下のコマンドを実行します。
```sh
docker run -itd -h db2server --name db2server  \
--privileged=true -p 50000:50000 \
-e LICENSE=accept -e DB2INST1_PASSWORD=Passw0rd icr.io/db2_community/db2
```

事前にpullしてあれば、あっさり瞬時に起動します。

が、内部でTaskが走っているので、以下のコマンドでログに`(*) Setup has completed.`が表示されるまで待ちます:
```
 docker logs -f  db2server
```

出力例：
```
~:$  docker logs -f  db2server

(*) Previous setup has not been detected. Creating the users...
(*) Creating users ...
(*) Creating instance ...
DBI1446I  The db2icrt command is running.


DB2 installation is being initialized.

 Total number of tasks to be performed: 4
Total estimated time for all tasks to be performed: 309 second(s)

Task #1 start
Description: Setting default global profile registry variables
Estimated time 1 second(s)
Task #1 end

Task #2 start
Description: Initializing instance list
Estimated time 5 second(s)
Task #2 end

Task #3 start
Description: Configuring DB2 instances
Estimated time 300 second(s)
Task #3 end

Task #4 start
Description: Updating global profile registry
Estimated time 3 second(s)
Task #4 end

The execution completed successfully.

For more information see the DB2 installation log at "/tmp/db2icrt.log.95".
DBI1070I  Program db2icrt completed successfully.


(*) Fixing /etc/services file for DB2 ...
07/05/2023 08:06:19     0   0   SQL1032N  No start database manager command was issued.
SQL1032N  No start database manager command was issued.  SQLSTATE=57019
(*) Cataloging existing databases
ls: cannot access '/database/data/db2inst1/NODE0000': No such file or directory
(*) Applying Db2 license ...

LIC1402I  License added successfully.


LIC1426I  This product is now licensed for use as outlined in your License Agreement.  USE OF THE PRODUCT CONSTITUTES ACCEPTANCE OF THE TERMS OF THE IBM LICENSE AGREEMENT, LOCATED IN THE FOLLOWING DIRECTORY: "/opt/ibm/db2/V11.5/license/en_US.iso88591"
(*) Saving the checksum of the current nodelock file ...
(*) Updating DBM CFG parameters ...
DB20000I  The UPDATE DATABASE MANAGER CONFIGURATION command completed
successfully.
DB20000I  The UPDATE DATABASE MANAGER CONFIGURATION command completed
successfully.
DB20000I  The UPDATE DATABASE MANAGER CONFIGURATION command completed
successfully.
No Cgroup memory limit detected, instance memory will follow automatic tuning
(*) Remounting /database with suid...

DB2 State : Operable
DB2 has not been started
Starting DB2...

07/05/2023 08:06:47     0   0   SQL1063N  DB2START processing was successful.
SQL1063N  DB2START processing was successful.
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
(*) All databases are now active.
(*) Setup has completed.
false

2023-07-05-08.06.47.177843+000 I29995E390            LEVEL: Warning
PID     : 14918                TID : 140315444266880 PROC : db2start
INSTANCE: db2inst1             NODE : 000
HOSTNAME: db2server
FUNCTION: DB2 UDB, base sys utilities, sqleReleaseStStLockFile, probe:16242
MESSAGE : Released lock on the file:
DATA #1 : String, 50 bytes
/database/config/db2inst1/sqllib/ctrl/db2strst.lck


```
ログに`(*) Setup has completed.`が表示されたら、Ctrl+Cで抜けます。

下の方の以下の部分に`(*) Setup has completed.`があります:
>SQL1063N  DB2START processing was successful.
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 
(\*) All databases are now active.
**(\*) Setup has completed.**

**[volume マウントについて]**
ちなみに[ドキュメントのプロシージャーのStep7](https://www.ibm.com/docs/ja/db2/11.5?topic=system-macos#taskt_install_db2CE_img__steps__1)では
`-v /Users/<username>/Docker:/database` のように
-vでローカルのディレクトリを/databaseにマウントしています。
しかし、これは不要です。
なにもつけなくても、docker上にvolumeを作成してくれます(/database用と/hadr用)。これによりdocker stopをして再度startした場合も、データの保持はされています。

（ここは検証結果です）
docker run後、2つvolumeが作成されています：
```
~:$ docker volume ls
DRIVER    VOLUME NAME
local     09cc3dd59f7365d8fa48164b6e9972ec69aee970a12b09652171b0f3b3b4ccf8
local     96cd43c7b0a94a7687b2ed8b80077d8cd9ecfc24e2e41d277233d53b0ddc0c47
~:$
```

これらのvolumeはコンテナ内の/databaseと/hadrにマウントされていました。
```
~:$ docker inspect db2server
[
    {
        "Id": "58ad3c62dff8f18703c3a6d881f52cba17a07f32ca2ef5b63036cf3931666ead",
        "Created": "2023-07-05T08:03:50.364202Z",
        "Path": "/var/db2_setup/lib/setup_db2_instance.sh",
        "Args": [],
        "State": {
           

（中略）

        "Mounts": [
            {
                "Type": "volume",
                "Name": "96cd43c7b0a94a7687b2ed8b80077d8cd9ecfc24e2e41d277233d53b0ddc0c47",
                "Source": "/var/lib/docker/volumes/96cd43c7b0a94a7687b2ed8b80077d8cd9ecfc24e2e41d277233d53b0ddc0c47/_data",
                "Destination": "/database",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "09cc3dd59f7365d8fa48164b6e9972ec69aee970a12b09652171b0f3b3b4ccf8",
                "Source": "/var/lib/docker/volumes/09cc3dd59f7365d8fa48164b6e9972ec69aee970a12b09652171b0f3b3b4ccf8/_data",
                "Destination": "/hadr",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
(以下省略)
````




# 5. 稼働確認
## 5-1. 起動しているコンテナにログインします。
```
docker exec -ti db2server bash -c "su - db2inst1"
```
出力例:
```
~:$ docker exec -ti db2server bash -c "su - db2inst1"

Last login: Tue Jul  4 13:36:38 UTC 2023 on pts/0
[db2inst1@db2server ~]$
```


## 5-2. サンプルデータベースを作成してみます
```
db2sampl -force -sql
```

出力例:
```
[db2inst1@db2server ~]$ db2sampl -force -sql

  Starting the DB2 instance...
  Creating database "SAMPLE"...
  Connecting to database "SAMPLE"...
  Creating tables and data in schema "DB2INST1"...
  Stopping the DB2 instance...

  'db2sampl' processing complete.

[db2inst1@db2server ~]$
```

## 5-3. DBに接続します
```
db2 connect to sample
```
出力例
```
[db2inst1@db2server ~]$ db2 connect to sample

   Database Connection Information

 Database server        = DB2/LINUXX8664 11.5.8.0
 SQL authorization ID   = DB2INST1
 Local database alias   = SAMPLE

[db2inst1@db2server ~]$
```

## 5-4. SELECTしてみます
```
db2 "select * from department" 
```

出力例
```
[db2inst1@db2server ~]$ db2 "select * from department"

DEPTNO DEPTNAME                             MGRNO  ADMRDEPT LOCATION
------ ------------------------------------ ------ -------- ----------------
A00    SPIFFY COMPUTER SERVICE DIV.         000010 A00      -
B01    PLANNING                             000020 A00      -
C01    INFORMATION CENTER                   000030 A00      -
D01    DEVELOPMENT CENTER                   -      A00      -
D11    MANUFACTURING SYSTEMS                000060 D01      -
D21    ADMINISTRATION SYSTEMS               000070 D01      -
E01    SUPPORT SERVICES                     000050 A00      -
E11    OPERATIONS                           000090 E01      -
E21    SOFTWARE SUPPORT                     000100 E01      -
F22    BRANCH OFFICE F2                     -      E01      -
G22    BRANCH OFFICE G2                     -      E01      -
H22    BRANCH OFFICE H2                     -      E01      -
I22    BRANCH OFFICE I2                     -      E01      -
J22    BRANCH OFFICE J2                     -      E01      -

  14 record(s) selected.

[db2inst1@db2server ~]$
```


## 5-5. DB接続を切断します
```
db2 connect reset
```

出力例
```
[db2inst1@db2server ~]$ db2 connect reset
DB20000I  The SQL command completed successfully.
[db2inst1@db2server ~]$
```

## 5-6. コンテナから抜けます
```
exit
```

出力例
```
[db2inst1@db2server ~]$ exit
logout
~:$
```

# (オプション)コンテナの停止、開始
コンテナの停止は以下のコマンドになります(db2特有ではないです。普通のdockerコマンドです):
```
docker stop db2server
```

停止したコンテナの開始は以下のコマンドになります(db2特有ではないです。普通のdockerコマンドです):
```
docker start db2server
```
すぐ開始するのですが、**起動時と同様に内部でTaskが走っているので、以下のコマンドでログに`(*) Setup has completed.`が表示されるまで待ちます**:
```
 docker logs -f  db2server
```
ログに`(*) Setup has completed.`が表示されたら、Ctrl+Cで抜けます。

# (オプション)コンテナの削除
コンテナを削除したい場合は、停止後、削除します。volumeは削除されないので、削除したい場合はコマンドで削除します。

1: コンテナの停止
```
docker stop db2server
```

2: コンテナの削除
```
docker rm db2server
```

3: volumeの削除
以下は使用していないvolumeを全て削除するコマンドです。
削除したくない使用していないvolumeがある場合は個別に`docker rm <volume名>`で削除してください。
```
docker volume prune
```

以上です。