ローカル環境用ストレージとして、S3 の代わりに MinIO (Rails & ActiveStorage & Docker使用) を使う
まえおき
細々と個人開発をしている。アーキテクト的にS3が必要なのだが、開発のためにわざわざS3を用意するのは何だか面倒。なんかローカルにS3的なものを構築できないかなー、と思っていたら「MinIO」という素敵なものを見つけたので、その時の作業メモ。
この記事では、Docker を使用した Rails + PostgressSQL の環境が出来上がっている状態で MinIO を導入して、ActiveStorageの向き先として設定するところまでを目標とする。
MinIO: https://min.io/
MinIO とは(雑)
AWS S3のAPIと互換性のあるオブジェクトストレージ。Github でコード公開はもちろん、DockerイメージまでDocker Hubに公開してくれてる。(素敵)
「まえおき」で書いたように、本番ではS3、開発/テスト では MinIO みたいな用途で使える。
MinIO: https://min.io/
github: https://github.com/minio/minio
Docker Hub: https://hub.docker.com/r/minio/minio
環境
Rails: 6.1.4
Ruby: 3.0.3
Docker Desktop: 4.4.2
前提条件
Docker を使用した Rails + PostgressSQL の環境が出来上がっている。
参考: https://zenn.dev/mochiblock/articles/aaa4724c6267e6
手順
1. Docker
docker-compose.yml
に以下を記述
version: '3'
services:
web:
# 内容は省略
db:
# 内容は省略
minio:
image: minio/minio:latest
environment:
MINIO_ROOT_USER: "minio"
MINIO_ROOT_PASSWORD: "minio123"
command: ["minio", "server", "/data", "--console-address", ":9001"]
volumes:
- minio:/data:cached
ports:
- "9000:9000"
- "9001:9001"
volumes:
db:
minio:
記述した上でdocker-compose up
をし、http://127.0.0.1:9001 にアクセスすると以下の画面が表示される。
ログインに必要な username
と password
は MINIO_ROOT_USER
, MINIO_ROOT_PASSWORD
で設定した値を使用。ここではminio
, minio123
となり、ログインに成功すると以下のような画面が表示される。
Note
- 古い記事だと
environment
でMINIO_ACCESS_KEY
,MINIO_SECRET_KEY
を使っているがこれらは非推奨となっているため、使うと起動時にWARNING
が出る。(参考記事: https://qiita.com/potdig/items/601aa883d87efbbbdc65)
バケット作成(Minio)
- http://127.0.0.1:9001 にアクセス & ログイン
- Buckets > Create Buckets > バケット名を入力して作成
2. aws-sdk-s3(Gem) を追加
gem "aws-sdk-s3", require: false
を Gemfile に追加 & bundle install
3. ActiveStorage
公式ドキュメント: https://railsguides.jp/active_storage_overview.html
マイグレーションファイル作成
`docker-compose exec web bin/rails active_storage:install` を実行。すると以下のようなマイグレーションファイルが生成される。
# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
# 内容省略
end
create_table :active_storage_attachments do |t|
# 内容省略
end
create_table :active_storage_variant_records do |t|
# 内容省略
end
end
end
生成後、docker-compose exec web bin/rails db:migrate
でマイグレーションを実行。
storage.yml の修正
ローカルのストレージ接続先を minio にするため、storage.yml
を以下のように修正する。
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
## 以下のように修正
local:
service: S3
access_key_id: minio
secret_access_key: minio123
endpoint: http://minio:9000
bucket: trainsns
region: us-east-1
force_path_style: true
Note
-
endpoint
はhttp://minio:9000
とすること。自分はhttp://127.0.0.1:9000
としていたせいで永遠とFailed to open TCP connection to localhost:9000
が発生ししばらく不毛な時間を過ごした。 -
force_path_style: true
をつけないとドメインがhttp://バケット名.minio:xxxx
となる- 詳しくはS3 のドキュメントに記載されている: https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Aws/S3/Client.html#initialize-instance_method
ActiveStorage
ここまででMinioへの接続が完了したので、あとは Active Storage ドキュメント: ファイルをレコードに添付する の通り
class User < ApplicationRecord
# 以下状況によって使い分け
has_one_attached :avatar
has_many_attached :images
end
のようにアタッチしたいモデルに適当なカラム名を追加すれば完成。
まとめ
複雑な設定とかはないけど、自分でやってみると結構つまずいたりした。
上記の設定 + フロントを React に明日場合の実装方法も同じ記事にしてしまおうかと思ったけど、全体的にまとまりがなくなりそうなので別記事で後日投稿する。
Discussion