こんにちは!
皆さんは開発中に S3 へファイルを上げたくて、
AWS のコンソールを開いて、IAM を用意して、バケットを作って……と遠回りしたことはないでしょうか?
本番は S3 なのに、手元では storage/app に逃がして、あとで差が出る。
ローカルから本物の S3 を叩くのも、課金と権限が気になって気が進みません。
そんなときに強い味方が MinIO です!
いま入れるなら、本家のイメージではなく pgsty/minio です。
§ 要約
MinIO は、S3 互換のオブジェクトストレージです。
手元で使うなら、コミュニティメンテの pgsty/minio:latest を引きます。
- 手元で S3 と同じ API が使える
- Docker 一発で立つ
- ブラウザのコンソールでバケットとオブジェクトが見られる
- アプリ側はエンドポイントを差し替えるだけ
以上!終わり!
正直それで終わりにしてもいいのですが、せっかくなのでもう少し説明します。
§ MinIO とは
元のプロジェクトはこちらです。
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 のまま - コンソールも入っている
- クライアントはコンテナ内の
mcli(mc互換)
イメージを 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 です。
初期ユーザ / パスワードは 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 に行きます。気をつけてください。
§ ブラウザで確認
ログインして、今作ったバケットとオブジェクトが出ていれば成功です。
アップロード、フォルダ、共有リンクまで、ここで完結します。
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、で揃えておけば、ディスクの差でハマることが減ります。
ローカルのオブジェクトストレージは、これで十分です!