RailsとCarrierWaveでAmazon S3に画像を保存する

Shunsuke Sawada

画像アップロード機能を素早く実装できる素敵Gem, CarrierWave。

(使い方はこちらの記事で)

画像の保存先をローカルにしていたけど、
herokuの使用を想定してAmazon S3にしてみたいと思います。

1年間ならheroku + Amazon S3 でサービス無料運営も可能かも?

herokuはPostgresqlが10,000レコードまで無料。(制限あり)
Amazon S3は1年間無料。(制限あり)

環境はruby2.0, Rails4です。

Amazon S3 登録

まずは登録。
クラウドコンピューティングならアマゾン ウェブ サービス | 仮想サーバー、ストレージ、データベースのための Amazon のクラウドプラットフォーム(AWS 日本語)

セキュリティ証明書のメニューをクリック。

Amazon S3

「新しいアクセスキーを作成する」で作成されます。
シークレットアクセスキーの項目で、「表示」をクリックすると確認できます。

Amazon S3

もし下記のような表示だったら、「legacy Security Credentials」をクリックすることで、上記のページにいけます。

Amazon S3

Backet 作成

Amazon S3上にスペースを確保します。

AWS Management Console をクリック。

Backet S3

Amazon S3 の項目があるので、クリック。

S3

Create Backet で 好きな名前を入れて作成。

Amazon S3

Region:から好きな場所が選べる。
パフォーマンスに影響するためサービスを提供する地域に近いRegionを選びましょう。

Amazon S3

なお、本番環境と開発環境で、保存先を変えたい時は、
2つ作成しても良いかもしれません。

アップローダーを編集

/uploaders/xxxx_uploader.rb

1
2
3
4
5
  # Local strage
  storage :file
#↓下記に変更
  # S3 strage
  storage :fog

/config/initializers/以下に
carrierwave.rbを作成してこんな感じに。

1
2
3
4
5
6
7
8
9
10
11
12
CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => 'your_access_key_id',
    :aws_secret_access_key  => 'your_secret_access_key',
    :region                 => 'chosen_region'
  }

  config.fog_directory = 'your_backet' if Rails.env.production?
  config.fog_directory = 'your_backet_for_dev' if Rails.env.development?

end

本番と開発でBacketを分けてみました。
:regionオプションはドキュメントにはoptionalとなっていますが、
Backetを作る際、Regionを指定した場合は、明示指定した方が良いと思います。

Backet作成時に「Tokyo」を選んだからといって、
:region => 'Tokyo'としてはいけません。
Regions and Endpoints から適切なものを選びましょう。

Tokyo なら、 :region => 'ap-northeast-1' ですね。

なお、設定しないオプションはコメントアウトか削除しておきましょう。

Gemfile編集

Carrierwave の設定で storage :fog としているので、
fog gem が必要です。

Gemfile

1
2
# For Carrierwave
gem 'fog', '~> 1.3.1'

$ bundle install とした時にエラーがでるかもしれません。

fog が nokogiri に依存しているとか。
でnokogiriをインストールしようとした時に必要なライブラリがないよ、とか。
環境によるでしょうが。

1
2
$ sudo yum install libxml2-devel
$ sudo yum install libxslt-devel

とかすると問題が解決するかも。

以上です。
通常通り、アプリから画像をアップロードすると、
Amazon S3へアップされているはず!。
Enjoy!

39
Shunsuke Sawada

おすすめの記事

CakePHP 2.x JSヘルパーでajax通信(ajax helperは使わない)
20
Rails4でQiita投稿ボタンをつくった
18
紙のデザイナーがウェブ開発できるようになるまでに必要なこと
451