TL;DR force_path_style: true
を指定してください
Amazon S3互換のMinIOはセルフホスティングできるS3として、開発用としても自宅の運用にも便利です。
これまで何回かActiveStorageのネタで投稿していますが、今まで手っ取り早くストレージの保存先はRailsのstorage
ディレクトリでした。
Dockerでコンテナイメージを作成するので特に自分で運用する場合はRailsでも良い気がしますが、前回のNginxと組み合わせるのにActiveStorageだけだと少々取り回しにくいなと思いました。
新しいRailsの作成はrails-promptなどを使ってもらうとして、storage.yml
の記述は以下のようにしました。
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: us-east-1
bucket: myapp
endpoint: http://localhost:9000
force_path_style: true
ここでのポイントは正しくregion
を指定すること、bucket
を指定すること、endpoint
を指定することです。
MinIO Docker Quickstart GuideをもとにDocker経由で作成したのでendpoint
はhttp://localhost:9000
です。
WebのUIはhttp://localhost:9001
でしたので注意。
続いてWebにMINIO_ROOT_USER
とMINIO_ROOT_PASSWORD
を入力してログインしたらhttp://localhost:9001/buckets
で上で指定したbucket
を作成しておきます。
DockerのVolumeを初期化したりするとログインして作成しないといけないのでややこしいですが、今回は割愛します。
続いてhttp://localhost:9001/settings
のEdit Region Configuration
でus-east-1
などに指定しておきました。
さて実際にRails側でこの設定でファイルをアップロードしてみると以下のエラーが表示されました。
Aws::S3::Errors::MalformedXML (The XML you provided was not well-formed or did not validate against our published schema.):
これはどうして起こるのかというと、エンドポイントのURLがhttp://myapp.localhost:9000
を指定しているみたいでした。
そこで冒頭のforce_path_style: true
を加えてあげることでhttp://localhost:9000/myapp
の形式に戻るというわけ。
相変わらずRails Guidesの方には記載がありませんが、今回はRails ActiveStorage Configuration for Minioというページを参考に解決しました。
またつい最近Cloudflare R2というサービスが追加されたので試してみたいところですね。