Laravel5からMinioObjectStorageに接続する

割と以前に[minioサーバーにさわった](http://qiita.com/aozora0000/items/e2cbdaf70c45cb564c21)んですが、リベンジマッチ！
という事で、今回はLaravel5.2からStorageファサードを経由してMinioサーバーに接続したいと思います。

# 準備
- minio
- Laravel5.2

尚、Laravelインストールは済んでいる物として進めます。

## minioインストール
https://github.com/minio/minio

- Mac利用ならhttps://github.com/minio/minio#os-x
- Linux利用ならhttps://github.com/minio/minio#gnulinux
- Windows利用ならhttps://github.com/minio/minio#microsoft-windows

を使ってください。

## minioサーバー立ち上げ
```
minio server [ファイル格納ディレクトリ]
```
これで起動します。

vagrantの場合は

```
minio server /vagrant/storages/
```
だとホストPCからファイルを直でチェック出来るのでオススメです。

## Filesystem/S3アダプタのインストール
```
php composer require league/flysystem-aws-s3-v3
```
今回はaws-php-sdkのversion3を利用します。

## MinioStorageServiceProviderの作成
```
php artisan make:provider MinioStorageServiceProvider
```

これでapp/Providers以下にMinioStorageServiceProviderが設置されています。
以下のように

```MinioStorageServiceProvider.php
<?php
namespace App\Providers;


use Aws\S3\S3Client;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\AwsS3v3\AwsS3Adapter;
use League\Flysystem\Filesystem;

class MinioStorageServiceProvider extends ServiceProvider
{
    public function boot()
    {
        \Storage::extend('minio', function ($app, $config) {
            $client = new S3Client([
                'credentials' => [
                    'key'    => $config["key"],
                    'secret' => $config["secret"]
                ],
                'region'      => $config["region"],
                'version'     => "latest",
                'endpoint'    => $config["endpoint"],
            ]);
            return new Filesystem(new AwsS3Adapter($client, $config["bucket"]));
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {

    }
}
```

## Storageファサードを環境で切り替えられるようにする

```config/filesystem.php
return [
    'default' => env("FILE_SYSTEM", "local"),
    'cloud' => 's3',
    'disks' => [
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],
        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'visibility' => 'public',
        ],
        's3' => [
            'driver' => 's3',
            'key' => env("S3_ACCESS_KEY"),
            'secret' => env("S3_ACCESS_SECRET"),
            'region' => env("S3_ACCESS_REGION"),
            'bucket' => env("S3_BUCKET_NAME"),
        ],
        'minio' => [
            'driver' => 'minio',
            'key' => env("S3_ACCESS_KEY"),
            'secret' => env("S3_ACCESS_SECRET"),
            'region' => env("S3_ACCESS_REGION"),
            'bucket' => env("S3_BUCKET_NAME"),
            'endpoint' => env("S3_ACCESS_ENDPOINT"),
        ]
    ],
];
```
これでStorageファサードの中のdisk設定で、minioを選択出来るようになります。
後は.envで

```.env
FILE_SYSTEM=minio
S3_ACCESS_KEY=[minio起動時に出るaccess_key]
S3_ACCESS_SECRET=[minio起動時に出るsecret_key]
S3_ACCESS_REGION=[minio起動時に出るregion]
S3_BUCKET_NAME=[利用したいバケット名]
S3_ACCESS_ENDPOINT=http://[minio起動サーバーのIP]:9000
```

こんな感じにしてやるだけで、Storageのデフォルト呼び出しが切り替えられます。
プロダクション環境ではs3、ローカルやVagrant・テストサーバーではminio という感じで使えますね。

# アップロード・ダウンロード
普通にputやget、existsが使えます。

```
\Storage::put("test.txt", "アップロードテスト");
```
 
```
if(\Storage::exists("test.txt")) {
    echo \Storage::get("test.txt");
}
```

# 感想
正直localのファイルストレージでもいいのですが・・・
社内ツール作成のデプロイがdocker imageだった為、手軽に永続化させたくてminioを選びました。
dockerを既に使っているなら

```
docker run -p 9000:9000 --name minio \
  --restart=always \
  -v /mnt/export/minio:/export \
  -v /mnt/config/minio:/root/.minio \
  minio/minio /export
```

こんな形で起動するだけですぐに使う事も出来るのでオススメです。

- 開発環境： Vagrant
- テスト環境： dokku
- プロダクション環境： AWS(予定)

なんていうサービスの作り方にピッタリだと思います。