手元の S3 は MinIO で揃える

LaravelAWSDockerOSSMinIO
手元の S3 は MinIO で揃える

こんにちは!

皆さんは開発中に S3 へファイルを上げたくて、
AWS のコンソールを開いて、IAM を用意して、バケットを作って……と遠回りしたことはないでしょうか?

本番は S3 なのに、手元では storage/app に逃がして、あとで差が出る。
ローカルから本物の S3 を叩くのも、課金と権限が気になって気が進みません。

そんなときに強い味方が MinIO です!
いま入れるなら、本家のイメージではなく pgsty/minio です。


§ 要約

MinIO は、S3 互換のオブジェクトストレージです。
手元で使うなら、コミュニティメンテの pgsty/minio:latest を引きます。

  • 手元で S3 と同じ API が使える
  • Docker 一発で立つ
  • ブラウザのコンソールでバケットとオブジェクトが見られる
  • アプリ側はエンドポイントを差し替えるだけ

以上!終わり!
正直それで終わりにしてもいいのですが、せっかくなのでもう少し説明します。


§ MinIO とは

元のプロジェクトはこちらです。

https://min.io/

Go 製の、S3 互換オブジェクトストレージです。
Put / Get / Delete、バケット、署名付き URL。アプリから見ると S3 です。
実体は自分のディスクです。

いま実際に pull するのは、こちらのフォークです。

https://hub.docker.com/r/pgsty/minio

https://github.com/pgsty/minio

Pigsty がメンテしている、MinIO 互換のコミュニティビルドです。
本家 MinIO, Inc. とは別物です。名前は互換の系統を示すために残っています。

知らんけど、一度慣れると「開発用に AWS を叩く」理由がかなり減ります。


§ なぜ本家じゃないのか

本家はコミュニティ向けの配布を止めています。
ソースは残っていますが、手元で docker pull minio/minio して使う、という形ではなくなりました。
商用は AIStor 側です。

開発用のローカル S3 が欲しいだけなのに、本家イメージを追いかける理由は薄いです。

pgsty/minio はその穴を埋めるフォークです。

  • S3 API、MINIO_*、ポート、ディスクの中身は MinIO のまま
  • コンソールも入っている
  • クライアントはコンテナ内の mclimc 互換)

イメージを pgsty/minio:latest に変えるだけで、あとの操作は昔の MinIO と同じです。


§ Docker で起動

とりあえず触るならこれだけです。

$ docker run -d --name minio \
  -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  pgsty/minio:latest server /data --console-address ":9001"

ポートの役割はこうです。

  • 9000 … S3 API(アプリが叩く方)
  • 9001 … Web コンソール(人が見る方)

--console-address ":9001" を付けないと、API とコンソールが同じポートに乗って分かりにくくなります。付けておきましょう。

立ったらブラウザで開きます。https ではなく http です。

http://localhost:9001

初期ユーザ / パスワードは minioadmin / minioadmin です。
空の Object Browser が出れば成功です。


§ compose に足す

普段の開発は compose に置いた方が楽です。
データも残したいので、ボリュームを付けます。

services:
  minio:
    image: pgsty/minio:latest
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    volumes:
      - minio-data:/data

volumes:
  minio-data:

アプリから見るホスト名はサービス名です。
この例なら minio、ポートは 9000

コンソールだけホストから見たい場合でも、API の 9000:9000 は残してください。
コンテナ同士なら内部ポートだけで届きますが、ホストの AWS CLI から試すときは公開が要ります。

パスワードは、手元でも minioadmin のままにしない方がよいです。
ただし 8 文字以上必要です。短いと起動しません。


§ バケットを作る

コンソールの Object Browser から Create Bucket でも足ります。
CLI なら、イメージに入っている mcli が楽です。本家の mc と同じ使い方です。

$ docker exec minio mcli alias set local http://127.0.0.1:9000 minioadmin minioadmin
$ docker exec minio mcli mb local/app-uploads

app-uploads のところは、アプリが使うバケット名に合わせてください。
本番のバケット名と同じにしておくと、設定の差がさらに減ります。

試しにファイルを置くなら、こうです。

$ docker exec minio sh -c 'echo hello minio > /tmp/hello.txt'
$ docker exec minio mcli cp /tmp/hello.txt local/app-uploads/hello.txt

コンソールをリロードすると、オブジェクトが見えます。


§ アプリの向き先

Laravel なら .env はだいたいこうです。
ディスクを s3 にして、エンドポイントだけ MinIO に向けます。

FILESYSTEM_DISK=s3

AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=app-uploads
AWS_ENDPOINT=http://minio:9000
AWS_USE_PATH_STYLE_ENDPOINT=true

ホストから直接叩くなら AWS_ENDPOINT=http://localhost:9000 です。
compose の中の PHP コンテナからなら、サービス名の http://minio:9000

AWS_USE_PATH_STYLE_ENDPOINT=true は付けてください。
MinIO は仮想ホスト形式より、パス形式の方が素直に動きます。
http://minio:9000/app-uploads/hello.txt という形です。

AWS CLI でも同じです。

$ aws --endpoint-url http://localhost:9000 s3 ls
$ aws --endpoint-url http://localhost:9000 s3 ls s3://app-uploads

--endpoint-url を忘れると、本物の AWS に行きます。気をつけてください。


§ ブラウザで確認

http://localhost:9001

ログインして、今作ったバケットとオブジェクトが出ていれば成功です。
アップロード、フォルダ、共有リンクまで、ここで完結します。

AWS 上で動かしている人は、セキュリティグループで 9000 / 9001 を開けないでください。
開ける相手は自分だけにしましょう。オブジェクトストレージを全世界に出す必要はありません。
開発用なら、localhost か VPN の内側で十分です。


§ まとめ

やることはこれだけです。

$ docker run -d --name minio \
  -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  pgsty/minio:latest server /data --console-address ":9001"

アプリの S3 エンドポイントを http://minio:9000(または http://localhost:9000)に向ける。
ブラウザで http://localhost:9001 を開く。

本家イメージは使わず、pgsty/minio:latest で十分です。
本番は S3、開発だけ MinIO、で揃えておけば、ディスクの差でハマることが減ります。
ローカルのオブジェクトストレージは、これで十分です!

この記事をシェアする