docker-composeでMinIO(S3互換)環境簡単構築

## 概要
ローカルの開発環境でS3と同じような環境を用意する方法をご紹介します。
(2022-10-12 更新版)

## 成果物
[GitHub](https://github.com/Akira-Demizu/developments/tree/main/minio)

## 環境
- maxOS Monterey 12.6
- Docker version 20.10.17
- Docker Compose version v2.10.2

## 構成
```
.
├── docker
│   └── minio
│       └── data
│           └── develop
│               └── .gitignore
├── .gitignore
└── docker-compose.yml
```

## 手順
### 1. docker-compose.yml作成
シンプルにminioコンテナのみ用意しています。
MinIOは頻繁にバージョン更新され、場合によっては正常に動作しなくなるのでバージョンを投稿時の最新版に固定しています。

```docker-compose.yml
version: '3.9'

services:
  minio:
    image: minio/minio:RELEASE.2022-10-08T20-11-00Z
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      - MINIO_ROOT_USER=minio
      - MINIO_ROOT_PASSWORD=minio123
    entrypoint: sh
    command: -c "/opt/bin/minio server /export --address :9000 --console-address :9001"
    volumes:
      - ./docker/minio/data:/export
```

### 2. デフォルトバケットの用意
今回は`develop`という名前のバケットを用意します。

#### 2.1 バケット用のディレクトリ
```sh
mkdir -p docker/minio/data/develop
```

#### 2.2 .gitignoreの用意
Gitを利用する場合は2種類の.gitignoreを用意しておくことをお勧めします。

**./.gitignore**

```.gitignore
docker/minio/data/.minio.sys/*
```

**./docker/minio/data/develop/.gitignore**
```docker/minio/data/develop/.gitignore
*
!.gitignore
```

### 3. 起動

```sh
docker-compose up -d
```

### 4. 確認
#### ログイン画面
http://localhost:9001/login にアクセスしてみましょう。
以下のようなログイン画面が表示されます。
docker-compose.ymlに記載している `minio / minio123` でログインできます。

![スクリーンショット 2022-10-12 10.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290840/0ad5ffdd-3bfa-f76b-d833-068c033956b6.png)

#### ログイン後(Buckets)
`develop` バケットが用意されています。

![スクリーンショット 2022-10-12 12.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290840/a729fe9e-c5bc-24d8-9cfe-7c005057cd40.png)


## おまけ
LaravelでAWS SDKを使う場合(ver 8.x)

### 1. SDKインストール
```
composer require league/flysystem-aws-s3-v3:^1.0
```

#### エラーが出る場合

```sh
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - league/flysystem-aws-s3-v3 1.0.0 requires aws/aws-sdk-php 3.*@dev -> satisfiable by aws/aws-sdk-php[3.0.0-beta.1, ..., 3.193.4].
    - league/flysystem-aws-s3-v3[1.0.1, ..., 1.0.25] require aws/aws-sdk-php ^3.0.0 -> satisfiable by aws/aws-sdk-php[3.0.0-beta.1, ..., 3.193.4].
    - league/flysystem-aws-s3-v3 1.0.x-dev is an alias of league/flysystem-aws-s3-v3 dev-master and thus requires it to be installed too.
    - aws/aws-sdk-php 3.0.x-dev is an alias of aws/aws-sdk-php dev-master and thus requires it to be installed too.
    - league/flysystem-aws-s3-v3[dev-master, 1.0.26, ..., 1.0.29] require aws/aws-sdk-php ^3.20.0 -> satisfiable by aws/aws-sdk-php[3.20.0, ..., 3.193.4].
    - aws/aws-sdk-php[dev-master, 3.173.20, ..., 3.193.4] require guzzlehttp/psr7 ^1.7.0 -> found guzzlehttp/psr7[1.7.0, ..., 1.x-dev] but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - aws/aws-sdk-php 3.0.0-beta.1 requires guzzlehttp/guzzle ~5.0 -> found guzzlehttp/guzzle[5.0.0, ..., 5.3.x-dev] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php 3.0.0 requires guzzlehttp/guzzle ^5.3 || ^6.0.1 -> found guzzlehttp/guzzle[5.3.0, ..., 5.3.x-dev, 6.0.1, ..., 6.5.x-dev] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php[3.0.1, ..., 3.3.4] require guzzlehttp/psr7 ~1.0 -> found guzzlehttp/psr7[1.0.0, ..., 1.x-dev] but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - aws/aws-sdk-php[3.3.5, ..., 3.18.28] require guzzlehttp/guzzle ~5.3|~6.0.1|~6.1 -> found guzzlehttp/guzzle[5.3.0, ..., 5.3.x-dev, 6.0.1, ..., 6.5.x-dev] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php 3.18.29 requires guzzlehttp/guzzle ~5.3.1|~6.2.1 -> found guzzlehttp/guzzle[5.3.1, ..., 5.3.x-dev, 6.2.1, 6.2.2, 6.2.3] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php[3.18.30, ..., 3.69.10] require guzzlehttp/guzzle ^5.3.1|^6.2.1 -> found guzzlehttp/guzzle[5.3.1, ..., 5.3.x-dev, 6.2.1, ..., 6.5.x-dev] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php[3.69.11, ..., 3.130.3] require guzzlehttp/guzzle ^5.3.3|^6.2.1 -> found guzzlehttp/guzzle[5.3.3, 5.3.4, 5.3.x-dev, 6.2.1, ..., 6.5.x-dev] but it conflicts with your root composer.json require (^7.0.1).
    - aws/aws-sdk-php[3.131.0, ..., 3.173.19] require guzzlehttp/psr7 ^1.4.1 -> found guzzlehttp/psr7[1.4.1, ..., 1.x-dev] but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - Root composer.json requires league/flysystem-aws-s3-v3 ^1.0 -> satisfiable by league/flysystem-aws-s3-v3[1.0.0, ..., 1.0.x-dev (alias of dev-master)].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

```

メッセージ通りオプション`--with-all-dependencies`をつければOKです。

```
composer require league/flysystem-aws-s3-v3:^1.0 --with-all-dependencies
```

### 2. configの設定
```php

<?php

return [
    ...

    'disks' => [
        ...

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'endpoint' => env('AWS_ENDPOINT', 'https://minio:9000'),
            'use_path_style_endpoint' => env('AWS_PATH_STYLE_ENDPOINT', false),
        ],

    ],

];
```

**注意**
endpointで接続先のサーバを指定することができるが、そのままだとバケット名がドメインの前についてしまいます。http://develop.minio:9000 な感じになってしまうのを防ぐために、use_path_style_endpointをtrueにしています。

### 3. .envの設定

```.env:.env
AWS_ENDPOINT=http://minio:9000
AWS_ACCESS_KEY_ID=minio
AWS_SECRET_ACCESS_KEY=minio123
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=develop
AWS_PATH_STYLE_ENDPOINT=true
```

**注意1**
AWS_ENDPOINTは`http://localhost:9090`にしがちですが、コンテナ間の通信の場合はコンテナ名がホスト名になるので注意が必要です。

**注意2**
configや.envを編集した際には必ずキャッシュを切りましょう。
[Laravel 粘着質なcacheを削除しよう！](https://qiita.com/A-Kira/items/5fd039217ba992481267)

### 3. 実装
```php
// アップロード
Storage::disk('s3')->put('test.txt', 'test');

// ダウンロード
Storage::disk('s3')->get('test.txt');
```

### 4. 確認
http://localhost:9001/login にアクセスしてみましょう。
`test.txt`が出来ていればOKです。

## 参考
- [【MinIO】Amazon S3をローカルで使用する方法](https://laid-back-scientist.com/minio)