LoginSignup
21
21

More than 5 years have passed since last update.

【CarrierWave】EC2上でS3に画像を保存する方法【MiniMagick】

Posted at

目標

tweettech1.gif

  • AWSのEC2インスタンス上で画像投稿を行い、ファイルがS3に投稿されるようにする。
  • EC2インスタンスや基本的な機能は作成済みのものとします。

手順

  • CarrierWaveを使用して画像を保存・表示できるように設定する
  • MiniMagickを使用して画像サイズを変えられるように設定する。
  • fogを使用して外部のストレージを使用できるよう設定する
  • AWSのS3に画像が保存されるように設定する
  • EC2インスタンス上で動作するよう設定する
  • デプロイする

CarrierWaveを使用して画像を保存・表示できるように設定する

  • CarrierWaveをインストールします。
Gemfile
gem 'carrierwave'
  • ターミナルでbundle installを実行します。
  • rails sでサーバーを再起動します。忘れるとuninitialized constantというエラーが出てしまうので気をつけましょう。

  • ターミナルでrails g uploader 画像を保存するカラム名を実行し、(カラム名)_uploader.rbを作成します。

ターミナル
rails g uploader image
  • 同時に、appディレクトリの中にuploadersディデクトリができます。
  • モデルでmount_uploaderを記述し、uploader.rbを読み込む設定をします。
tweet.rb
class Tweet < ApplicationRecord
  belongs_to :user

  # mount_uploader :カラム名, uploader名(大文字でつなげる)
  mount_uploader :image, ImageUploader
end

  • 下記のように画像を保存するフォームを用意します。form_forの場合だとf.file_field :カラム名となります。
tweet.html.erb
<%= form_for(@item) do |f| %>
  <div class="field">
    <%= f.text_area :content %>
    <%= f.file_field :image %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
  • コントローラーでストロングパラメーターを設定している場合は忘れずにカラム名を追記しましょう。
tweets_controller
def tweet_params
  params.require(:tweet).permit(:content, :image)
end
  • deviseのカラムに保存する場合はapplication_controllerでストロングパラメーターを設定します。
  • デフォルトにないカラム名をkeysに記述します。(例ではiconwallpaper
application_controller
 before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:icon, :wallpaper])
    devise_parameter_sanitizer.permit(:account_update, keys: [:icon, :wallpaper])
  end
  • 画像を表示するにはimage_tagを使用します。カラム名に.urlをつけるのを忘れずに。
views/tweets/index
<%= image_tag @tweet.image.url %>
  • これでローカル環境で画像をアップロードできます。

MiniMagickを使用して画像サイズを変えられるように設定する

  • 画像加工処理のgemとしてRMagickが有名ですが、エラーが多発するため、ほぼ同じことができるMiniMagickの使用をオススメします。
gem 'mini_magick'
  • bundle installとサーバーの再起動を忘れずに。

  • MiniMagickの使用にはImageMagickをインストールする必要があります。

  • which convertでパスが表示されればインストールされています

  • インストールされていない場合はbrew install imagemagickでインストールします

ターミナル
MikanBook-Pro:tweet-tech mikan3rd$ which convert
/usr/local/bin/convert
  • uploader.rbを編集します。include CarrierWave::MiniMagickと記述しましょう。
  • 画像サイズを変えるにはresize_to_fitresize_to_limitを使います。[横サイズ, 縦サイズ]と指定します。
  • extension_white_listを定義することで拡張子を指定できます。
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick

  strage :file

  process resize_to_limit: [500, 500]

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end
  • 他にも別で画像を保存するカラムがある場合はrails g uploader 画像を保存するカラム名で新たにuploaderファイルを作成し、同様の方法で設定します。
  • 同じ画像を違うサイズで保存したい場合、下記のようにversionを指定します。
  • この場合、<%= image_tag @tweet.image.garalley.url %><%= image_tag @tweet.image.thumb.url %>のように、カラム名の下にversion名を加えることで、そのversionの形式の画像を表示できます。
image_uploader
class ImageUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick

  version :garalley do
    process resize_to_fit: [200, 200]
  end

  version :thumb do
    process resize_to_fit: [100, 100]
  end

end

  • 単純に、CSSのwidth/heightで調整することもできます。

fogを使用して外部のストレージを使用できるよう設定する

  • fogをインストールします。fogは画像をアップロードする際、外部のストレージを選択してアップロードするのを補助してくれるgemです。
Gemfile
gem 'fog'
  • bundle installとサーバーの再起動を忘れずに。
  • uploader.rbでstrageをfogにします。
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick

  process resize_to_limit: [550, 500]

  # storage :file から :fog に変更
  storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end
  • これでfogを使う準備ができました

AWSのS3に画像が保存されるように設定する

  • AWSの「サービス」で「S3」を選択し、バケットを作成しましょう。
  • 日本の場合、リージョンは「アジアンパシフィック(東京)」にしましょう。

  • config/initializersディレクトリにcarrierwave.rbを作成します。

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

CarrierWave.configure do |config|
  config.storage = :fog
  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    region: ENV['AWS_REGION']
  }

    case Rails.env
    when 'development'
        config.fog_directory  = ENV['AWS_BUCKET_NAME']
        config.asset_host = ENV['AWS_BUCKET_URL']
    when 'production'
        config.fog_directory  = ENV['AWS_BUCKET_NAME']
        config.asset_host = ENV['AWS_BUCKET_URL']
    end
end
  • まずはローカル環境で動作するように、環境変数を.bash_profileに記述します。
  • 環境変数とはサーバに登録して参照できる変数で、外部に漏らしたくないパスワードなどの情報を設定します。
ターミナル
MikanBook-Pro:tweet-tech mikan3rd$ cd
MikanBook-Pro:~ mikan3rd$ vi .bash_profile
.bash_profile
export AWS_ACCESS_KEY_ID=*******************
export AWS_SECRET_ACCESS_KEY=************************
export AWS_REGION=ap-northeast-1
export AWS_BUCKET_NAME=mikan3rd-tweet-tech
export AWS_BUCKET_URL=https://s3-ap-northeast-1.amazonaws.com/mikan3rd-tweet-tech
  • バケットのリージョンが東京の場合、export AWS_REGION=ap-northeast-1となります。他の項目も例にならって設定しましょう。

  • Railsのディレクトリに戻ってからsource ~/.bash_profileで.bash_profileを再読み込みします。

  • サーバーも再起動します

ターミナル
MikanBook-Pro:~ mikan3rd$ cd projects/tweet-tech/
MikanBook-Pro:tweet-tech mikan3rd$ source ~/.bash_profile
MikanBook-Pro:tweet-tech mikan3rd$ rails s
  • 以上で画像の保存先をS3に設定できました

EC2インスタンス上で動作するよう設定する

  • デプロイ前に、EC2で環境変数の設定とImageMagickのインストールを行う必要があります。
  • EC2にログイン後、sudo vim /etc/environmentで環境変数を設定します。
  • ImageMagickのインストール方法はいくつかあるようですが、私は下記の方法でインストールできました。
  • https://gist.github.com/ARolek/9199329

デプロイする

  • 以上です

内容に不備等ありましたら、お手数ですがコメントにてお願いします。

21
21
1

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
21
21