Amazon S3は、Amazon Web Servicesの中核をなす非常に強力なサービスです。しかし、本番環境以外では、S3を使うのは難しいかもしれない。アクセス・キーの受け渡し、ユーザー・アカウントのプロビジョニング、信頼できるネットワーク接続の維持が必要であり、お金がかかることは言うまでもない。幸運なことに、この問題を解決するツールが存在する。FakeS3は、本物のS3の動作をシミュレートする軽量なサーバーだ。Amazon S3が応答するのと同じ呼び出しに応答し、アップロードされたファイルをローカルのファイルシステムに保存する。gemはS3のコマンド一式をサポートしていませんが、実装されているAPIはほとんどのアプリケーションのユースケースに十分です。
この記事では、Active Recordで人気のファイル添付ライブラリであるPaperclipと、AWSとFakeS3を統合するアプローチを紹介する。PaperclipとS3を組み合わせることで、Paperclipの便利なコア機能(バリデーション管理や画像変換など)とオンラインストレージの利点を組み合わせた効果的なファイルストレージシステムが実現します。これらのツールの設定は自明ではなく、詳細なドキュメントを調べたり、多くのgem固有の問題を解決したりする必要がありますが、開発をより迅速かつ効率的にするために時間を費やす価値はあります。
我々の目標は何か?
記述されたツールの統合には3つのステップが必要である:
- FakeS3 gemが提供するS3 fakeserverをバックグラウンドで起動する。
- AWS S3クライアントがすべてのリクエストを起動したフェイクサーバーに委譲するように設定する。
- ビルドしたリソースのURLで偽のS3エンドポイントを使用するようにPaperclipを設定する。
インストール
必要なgemをインストールすることから始めよう:
# ジェムファイル
gem "paperclip"
gem "aws-sdk", "~> 1.6"
gem "fakes3", group:グループ: [:development, :test]
aws-sdkのバージョン1.6を必ずインストールしてください。Amazonのサービスでストレージを管理するためにSKDを使用するPaperclipは、このgemの上位バージョンではうまく動作しません。これはバージョン2.0でSDKのAPIが大幅に変更されたためです。
また、FakeS3の主な目的は、実行時の依存関係を最小限に抑えることであることを覚えておいてほしい。FakeS3は、S3コールをテストするための開発ツールである。 コード むしろ、S3の機能を複製しようとしている本番サーバーの方が重要です。したがって、gemは開発グループとテストグループにのみ含めるべきである。
AWSの設定
AWS SDK は、設定のロードを担当する専用のヘルパーメソッドを提供します。デフォルトでは config/aws.yml
まず、イニシャライザーで以下のメソッドを呼び出す。まず、イニシャライザで以下のメソッドを呼び出します:
# config/initializers/aws.rb
AWS::Rails.load_yaml_config
さて、コンフィギュレーション・ファイルが正しく読み込まれたので、次はその内容を指定しよう:
# config/aws.yml
開発: &development
access_key_id:"abc"
secret_access_key:"abc"
s3_endpoint: "localhost"
s3_port:10001
s3_force_path_style: true
use_ssl: false
テスト*開発
それでは、すべてのパラメーターについてひとつずつ説明していこう:
access_key_id, secret_access_key
- Amazonのアカウントにアクセスするために必要なAWSクライアントの認証情報。これらは偽のS3サーバーによって無視されるため、サンドボックス環境ではカスタム値となります。s3_endpoint, s3_port
- S3エンドポイントの仕様。これらのパラメータを使用して、本物のS3エンドポイントをFakeS3 gemによって起動された偽のエンドポイントに置き換えます。s3_force_path_style
- S3では、バケット名をURLに含める際に2つのスタイルを選択できます。バケット名をドメインスタイル(bucket.s3.amazonaws.com)にするか、パススタイル(s3.amazonaws.com/bucket)にするかを選択できます。物事をシンプルに保ち、バケツのサブドメインとループバックアドレスのマッピングに関連する余分な設定を避けるために、私は開発環境ではドメインスタイルよりもパススタイルを好みます。use_ssl
- は、AWS SDK がバニラ HTTP ではなく HTTPS を使用するように強制します。FakeS3 gemはAWSクライアントがデフォルトで実行するHTTPSリクエストをサポートしていないため、このオプションを無効にする必要があります。
本番環境での設定は非常に簡単だ:
# config/aws.yml
プロダクション: &production
access_key_id: %
secret_access_key: %
ステージング*プロダクション
しかし、今回は本物のS3サービスを扱うので、本物のAWS認証情報を提供する必要がある。
潜在的なセキュリティー・リスクがあるため、アクセス・キーのような秘密の値は、環境変数などを使ってバージョン管理システムから除外するのが良い方法だ。ERBを使って、その値を設定ファイルに注入する。
ペーパークリップ構成
さて、いよいよPaperclipと向き合い、すでに設定済みのS3クライアントとうまく連携するように強制する番だ。Paperclipの設定の主な目的は、fakeserverがホストするリソースを見つけるストレージパスを取得することだ:
localhost:10001/:バケット名/:パス
もう一度、開発環境から説明しよう:
# config/paperclip.yml
開発: &development
ストレージ: :s3
バケット"development"
s3_host_name: "localhost"
url:":s3_alias_url"
パス":class/:attachment/:id_partition/:style/:filename.:extension"
s3_host_alias: "localhost:10001/development"
テスト:*開発
ストレージ
- はストレージキャリアを指定します(デフォルトはローカルファイルシステム)。AWS S3を使用しているので、次のように変更する必要がある。:s3
.バケット
- ファイルを保存するS3バケットの名前。バケットが存在しない場合は、Paperclipが作成を試みます。url
- に設定する。:s3_alias_url
で指定した値でS3バケットのホスト名をエイリアスします。s3_host_alias
パラメータが必要だ。s3_host_alias
- デフォルトのS3バケットのホストのエイリアスです。ホスト、ポート、バケット名の配置がAWSクライアントの設定と一致していることに注意してください。パス
- ファイルを Bucket に格納するキーのパターンを指定します。キーはファイル名のようにバケット内で一意でなければなりません。S3はディレクトリをサポートしていないため/
シンボルでディレクトリ構造をシミュレートする。
# config/paperclip.yml
プロダクション: &production
ストレージ: :s3
バケット:
url: ":s3_domain_url"
パス ":class/:attachment/:id_partition/:style/:filename.:extension"
ステージング*プロダクション
AWSのクレデンシャルと同様に、バケット名もコードベースの外に保存すべき秘密の値であると考えられている。環境変数に格納することをお勧めします。
最後に、イニシャライザでPaperclipのデフォルトオプションに設定をマージします:
# config/initializers/paperclip.rb
paperclip_defaults = Rails.application.config_for :paperclip
paperclip_defaults.symbolize_keys!
Paperclip::Attachment.default_options.merge! paperclip_defaults
ランニングフェイク3
AWSとPaperclipの両構成には、ローカルのS3フェイクサーバーへの参照が含まれている。 ローカルホスト:10001
.開発作業を行う前に、以下のコマンド(FakeS3 gemで提供されている)でサーバーを起動する必要があります:
fake3 -r public/system -p 10001
渡されるパラメーターは以下の通り:
ルート
- ルートディレクトリにアップロードされたファイルが保存されます。アップロードされたファイルをリポジトリに保存したくない場合は、VCSから除外することを検討してください。ポート -p
- ローカル・サーバーが実行されるポート番号。
アプリケーションのプロセス管理にForemanを使用している場合、Procfileに以下のエントリーを追加すると便利です:
# プロファイル
fakes3: fakes3 -r ${FAKES3_STORAGE_PATH:-public/system}。-p ${FAKES3_PORT:-10001}
これにより、S3関連の機能を開発する必要があるたびにfakeserverを起動する時間を節約することができる。
結論
すべてのリクエストをローカルのフェイクサーバに委譲するようにAWSクライアントを設定し、構築したリソースのURLで偽のS3エンドポイントを使用するようにPaperclipを設定し、すべてのファイルをローカルのファイルシステムに格納する偽のS3 gemが提供するフェイクサーバを起動した。
その結果、私たちはインターネット接続から独立し、コストを削減することができた。