目標
- 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
に記述します。(例ではicon
とwallpaper
)
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_fit
やresize_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
デプロイする
- 以上です
内容に不備等ありましたら、お手数ですがコメントにてお願いします。