👏

ローカル環境用ストレージとして、S3 の代わりに MinIO (Rails & ActiveStorage & Docker使用) を使う

2022/02/16に公開

まえおき

細々と個人開発をしている。アーキテクト的に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 に以下を記述

docker-compose.yaml
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 にアクセスすると以下の画面が表示される。

ログインに必要な usernamepasswordMINIO_ROOT_USER, MINIO_ROOT_PASSWORD で設定した値を使用。ここではminio, minio123となり、ログインに成功すると以下のような画面が表示される。

Note

バケット作成(Minio)

  1. http://127.0.0.1:9001 にアクセス & ログイン
  2. 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` を実行。すると以下のようなマイグレーションファイルが生成される。
db/migrate/タイムスタンプ_create_active_storage_tables.active_storage.rb
# 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 を以下のように修正する。

config/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

  • endpointhttp://minio:9000 とすること。自分は http://127.0.0.1:9000 としていたせいで永遠と Failed to open TCP connection to localhost:9000 が発生ししばらく不毛な時間を過ごした。
  • force_path_style: true をつけないとドメインが http://バケット名.minio:xxxx となる

ActiveStorage

ここまででMinioへの接続が完了したので、あとは Active Storage ドキュメント: ファイルをレコードに添付する の通り

app/models/user.rb
class User < ApplicationRecord
  # 以下状況によって使い分け
  has_one_attached :avatar
  has_many_attached :images
end

のようにアタッチしたいモデルに適当なカラム名を追加すれば完成。

まとめ

複雑な設定とかはないけど、自分でやってみると結構つまずいたりした。
上記の設定 + フロントを React に明日場合の実装方法も同じ記事にしてしまおうかと思ったけど、全体的にまとまりがなくなりそうなので別記事で後日投稿する。

参考資料

Discussion