ActiveStorageでMinIOにアップロードする方法

October 02, 2021

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経由で作成したのでendpointhttp://localhost:9000です。 WebのUIはhttp://localhost:9001でしたので注意。

続いてWebにMINIO_ROOT_USERMINIO_ROOT_PASSWORDを入力してログインしたらhttp://localhost:9001/bucketsで上で指定したbucketを作成しておきます。 DockerのVolumeを初期化したりするとログインして作成しないといけないのでややこしいですが、今回は割愛します。 続いてhttp://localhost:9001/settingsEdit Region Configurationus-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というサービスが追加されたので試してみたいところですね。


Profile picture

Personal blog by Seiichi Yonezawa.