1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

adobe/s3mockでS3をモック化する

Last updated at Posted at 2023-06-04

はじめに

adobe/s3mockを使うことでAWS S3をモック化することができます。
ローカル開発環境のDockerにadobe/s3mockを追加することで、実際のAWS S3を利用せずともS3の機能を実現することができます。

導入方法

adobe/s3mockの追加

docker-compose.ymlに下記を追加することでadobe/s3mockを利用することができます。

docker-compose.yml
services:
  web:
    ...
+  s3:
+    image: adobe/s3mock
+    environment:
+      - initialBuckets=my-bucket
+      - retainFilesOnExit=true
+      - root=/s3mock
+    ports:
+      - "9090:9090"
+    volumes:
+      - s3_data:/s3mock
  volumes:
+  s3_data:
      ...

environmentinitialBucketsを指定することで、最初からバケットを作成しておくことができます。

retainFilesOnExittrueに指定し、rootで指定したパスをvolume化することで、
投稿した画像を永続化することができます。

aws-sdk-s3を使用した画像投稿

adobe/s3mockを導入できたので、早速aws-sdk-s3を使用して画像を投稿したいと思います。
まずGemfileaws-sdk-s3を追加します。

Gemfile
gem 'aws-sdk-s3', '~> 1'

config/initializers/aws.rbなどのファイルを作成して、region, credentialsを設定します。
ローカル環境でadobe/s3mockを使用する場合は、endpoint'http://s3:9090's3docker-compose.ymlに記載したサービス名)、force_path_styletrueに指定します。
AWS上のS3に実際アクセスはしないので、ENV["AWS_ACCESS_KEY"]ENV["AWS_SECRET_ACCESS_KEY"]は適当な値で大丈夫です。

config/initializers/aws.rb
Aws.config.update({
  region: 'ap-northeast-1',
  credentials: Aws::Credentials.new(ENV["AWS_ACCESS_KEY"], ENV["AWS_SECRET_ACCESS_KEY"])
})

if Rails.env.development?
  Aws.config.update({
    endpoint: 'http://s3:9090',
    force_path_style: true
  })
end

動作確認

initialBucketsmy-bucketを指定しているので、デフォルトでmy-bucketのバケットが作成されていることが確認できます。

s3 = Aws::S3::Resource.new
s3.buckets.each {|b| p b.name }
=> "my-bucket"

画像をアップロードすることもできます。

file_path = Rails.root.join('sample.jpg')
obj = s3.bucket('my-bucket').object('image/sample.jpg')
obj.upload_file(file_path)

署名付URLを発行しアップロードした画像を表示することもできます。
ただし、endpointhttp://s3:9090を指定しているため、デフォルトでは
http://s3:9090/my-bucket/image/sample.jpg?から始まるURLが発行され
そのままではブラウザから画像を表示することができません。

なので、画像を表示する際にはendpoint'http://localhost:9090'に指定するといいと思います。

client = Aws::S3::Client.new(endpoint: 'http://localhost:9090')
signer = Aws::S3::Presigner.new(client: client)
@url = signer.presigned_url(:get_object, bucket: 'my-bucket', key: 'image/sample.jpg')
=> "http://localhost:9090/my-bucket/image/sample.jpg?から始まるURL"

生成した@urlimage_tagで実際に表示することができます。

index.html.erb
<%= image_tag @url %>

スクリーンショット 2023-06-04 15.38.55.png

CarrierWaveを使用した画像投稿

Gemfilecarrierwavefog-awsを追加します。

Gemfile
gem 'carrierwave'
gem 'fog-aws'

ローカル環境でadobe/s3mockを使用する場合は、endpoint'http://s3:9090'force_path_styletrueに指定します。
ブラウザから画像を表示することができるよう
config.asset_hostには'http://localhost:9090/my-bucket'を指定します。

config/initializers/carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
  if Rails.env.development?
    config.storage :fog
    config.fog_provider = 'fog/aws'
    config.fog_directory  = 'my-bucket'
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['AWS_ACCESS_KEY'], 
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], 
      region: 'ap-northeast-1',   
      endpoint: 'http://s3:9090',
      path_style: true
    }
    config.asset_host = 'http://localhost:9090/my-bucket'
  end
end

後は、画像を投稿したいモデルに「アップロード画像用のカラム」と「アップローダークラス」を用意し、
アップローダークラスのstorage:fogにすることでadobe/s3mockを使用した画像投稿が行えます。

storage :fog

スクリーンショット 2023-06-04 15.44.54.png

スクリーンショット 2023-06-04 15.45.11.png

ActiveStorageを使用した画像投稿

S3を利用するActiveStorageの設定にすれば大丈夫です。
'aws-sdk-s3'を利用するので、endpointなどの設定はconfig/initializers/aws.rbでしているので追加で設定を行う必要はありません。

config_environments/development.rb
config.active_storage.service = :amazon
config/storage.yml
amazon:
  service: S3
  access_key_id: <%= ENV["AWS_ACCESS_KEY"] %>
  secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %>
  region: ap-northeast-1
  bucket: my-bucket

注意点

ActiveStorageを使用する場合、endpoint'http://s3:9090'のままなので
このままだとブラウザから画像を表示することができません。
なので、ブラウザで画像も表示したい場合はさらにもう一工夫してあげる必要がありそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?