Docker Composeで立てたMinIOにmc/AWS CLI/Boto3で接続してみる

# MinIOとは

- Amazon S3と互換性のあるOSSのオブジェクトストレージ
- 2014年に設立されたMinIO, Inc.によって開発されている
- Amazon S3と互換性があるため、AWS CLIやAWS SDKからアクセス可能
- ただしAmazon S3が提供している全てのインタフェースをMinIOが提供しているわけではないため注意
- GitHubリポジトリ: https://github.com/minio/minio

# Docker Composeの設定

```yaml:docker-compose.yml
services:
  minio:
    # イメージは現時点で最新のものを指定している
    image: quay.io/minio/minio:RELEASE.2023-01-12T02-06-16Z
    container_name: minio
    ports:
      - 9000:9000
      - 9001:9001
    # ユーザ名/パスワードの設定
    # 特に設定しない場合、minioadmin/minioadminが暗黙的に設定される
    # ドキュメント: https://min.io/docs/minio/linux/administration/identity-access-management/minio-user-management.html
    environment:
      - MINIO_ROOT_USER=root
      - MINIO_ROOT_PASSWORD=password
    command: server /data --console-address ":9001"
    # データの永続化
    volumes:
      - ./docker/minio/data:/data
```

# コンテナの起動

```bash
# コンテナの起動
$ docker compose up -d

# 起動していることを確認
$ docker compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
minio               "/usr/bin/docker-ent…"   minio               running             0.0.0.0:9000-9001->9000-9001/tcp
```

# Web UIの操作

- Webブラウザ上で `http://localhost:9001` を開くとMinIOのWeb UIにアクセスできる
- `Username` と `Password` には `docker-compose.yml` に設定した `MINIO_ROOT_USER` と `MINIO_ROOT_PASSWORD` を入力する

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78249/a5e82851-c265-08e7-61d9-def9dcd7a3c6.png)

- ログイン後の画面
- MinIOの一通りの操作が可能
    - e.g. バケットの操作、オブジェクトの操作、ユーザの操作、監視、etc ...

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78249/d7fbc302-56be-03db-d30c-cee46a230b90.png)

# 各種方式で接続

- 事前にアクセスキーの発行が必要
- アクセスキーはMinIOのWeb UIから発行が可能

## mcで接続

- MinIO Client(mc)からMinIOに接続してみる
- mcはMinIOの公式のクライアント
- GitHubリポジトリ: https://github.com/minio/mc

```bash
# mcのインストール
$ brew install minio/stable/mc

# バージョン確認
$ mc -v
mc version RELEASE.2023-01-11T03-14-16Z (commit-id=14c2e506fa78b53fb6db88bcf87d8f6d3fb6989e)
Runtime: go1.19.4 darwin/amd64
Copyright (c) 2015-2023 MinIO, Inc.
License GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>

# エンドポイントのエイリアスとアクセスキーの設定
# エイリアス名、エンドポイント、アクセスキー、アクセスシークレットキーの順で指定する
$ mc alias set minio http://localhost:9000 XXXXXXXXXX XXXXXXXXXXXXXXXXXXXX
Added `minio` successfully.

# バケットの確認
$ mc ls minio
[2023-01-17 15:32:49 JST]     0B test/

# バケット内のオブジェクトの確認
$ mc ls minio/test
[2023-01-17 15:33:27 JST]  94KiB STANDARD kazukichi.png

# オブジェクトのダウンロード(保存先はカレントディレクトリ)
$ mc cp minio/test/kazukichi.png .
...0/test/kazukichi.png: 94.45 KiB / 94.45 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.48 MiB/s 0s

# オブジェクトのアップロード
$ mc cp ./takashi.jpg minio/test
...-example/takashi.jpg: 15.23 KiB / 15.23 KiB ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 580.18 KiB/s 0s
```

## AWS CLIで接続

- インストール方法: https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
- GitHubリポジトリ: https://github.com/aws/aws-cli

```bash
# バージョン確認
$ aws --version
aws-cli/2.9.15 Python/3.9.11 Darwin/21.6.0 exe/x86_64 prompt/off

# 一時的にMinIOのアクセスキーを使用できるようにする
$ export AWS_ACCESS_KEY_ID=XXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX

# バケットの確認
# エンドポイントにMinIOを指定する
$ aws --endpoint-url http://localhost:9000 s3 ls
2023-01-17 15:32:49 test

# バケット内のオブジェクトの確認
$ aws --endpoint-url http://localhost:9000 s3 ls s3://test/
2023-01-17 15:33:27      96712 kazukichi.png

# オブジェクトのダウンロード(保存先はカレントディレクトリ)
$ aws --endpoint-url http://localhost:9000 s3 cp s3://test/kazukichi.png .
download: s3://test/kazukichi.png to ./kazukichi.png

# オブジェクトのアップロード
aws --endpoint-url http://localhost:9000 s3 cp ./takashi.jpg s3://test/
upload: ./takashi.jpg to s3://test/takashi.jpg
```

## Boto3で接続

- Boto3とはAWS SDK for Pythonのこと
- GitHubリポジトリ: https://github.com/boto/boto3

```bash
# インストール
$ pip install boto3
```

- ソースコード

```python
import boto3

minio = boto3.resource(
    's3',
    endpoint_url='http://localhost:9000',
    aws_access_key_id='XXXXXXXXXX',
    aws_secret_access_key='XXXXXXXXXX',
)

# バケットの確認
print("buckets")
for bucket in minio.buckets.all():
    print("> " + bucket.name)

print()

# バケット内のオブジェクトの確認
print("objects")
bucket = minio.Bucket("test")
for obj in bucket.objects.all():
    print("> " + obj.key)
```

- 実行結果

```bash
$ python example.py
buckets
> test

objects
> kazukichi.png
> takashi.jpg
```