S3にアップしたファイルをCloudFrontを通して配信するケースはよくあると思うのですが、ものによってはCloudFrontのキャッシュを効かせたくないファイルが出てきたりします。
「都度個別対応とか必要なのかなーどうなのかなー」と思ったら、ばっちりAWSのサポートにありました。
CloudFront がファイルをキャッシュするのを防ぐ
Amazon CloudFront が特定のファイルをキャッシュしないようにするには、オリジンかディストリビューションのどちらかで、次に挙げるいずれかの設定を行います。
オリジンでの設定
カスタムオリジンウェブサーバーのアプリケーションで、CloudFront にキャッシュさせたくないオブジェクトに、Cache-Control no-cache、no-store、または private ディレクティブを追加します。Amazon Simple Storage Service (S3) をオリジンとして使用してる場合は、オブジェクトメタデータを使用して、特定の Cache-Control ヘッダーを追加することができます。
ディストリビューションでの設定
Amazon CloudFront コンソールで、ディストリビューションを開いてから、CloudFront にキャッシュさせたくないファイルを配信するキャッシュ動作を開きます。確実にキャッシュ動作の [Minimum TTL] が 0 秒間に設定されていることを確認してください。
注意: [Object Caching (オブジェクトキャッシング)] について、[Use Origin Cache Headers (オリジンキャッシュヘッダーの使用)] が選択されている場合、[Minimum TTL] はデフォルトで 0 です。[カスタマイズ] が選択されている場合、[Minimum TTL] を 0 に変更する必要があります。
CarrierWaveでの場合
RailsでCarrierWaveを使っている場合は下記のような感じでfog_attributes
で設定できるので、ささっと「これだけ…!」な対応がしたい場合は、オリジンでno-cache
設定で良いかもしれないです。
CarrierWave.configure do |config| config.fog_provider = 'fog/aws' ...(略)... config.fog_attributes = { 'Cache-Control' => 'no-cache' } end
uploaderごとの対応
uploaderが複数あるとき、uploaderごとにcacheの設定を分けたい場合は、uploaderでfog_attributes
を追加することで、個別の対応ができます。
# config/initializers/carrierwave.rb CarrierWave.configure do |config| config.fog_provider = 'fog/aws' ...(略)... config.fog_attributes = { 'Cache-Control' => 'public, max-age=604800' } end
HogeUploaderではデフォルト(CarrierWave.configure
の設定)まま
# app/uploaders/hoge_uploader.rb class HogeUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick end
PiyoUploaderではno-cache
を設定
# app/uploaders/piyo_uploader.rb class PiyoUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick # PiyoUploaderではno-cacheの設定を追加 def fog_attributes { 'Cache-Control' => 'no-cache' } end end
consoleで確認すると↓の感じに。
$ rails c > HogeUploader.new.fog_attributes #=> { 'Cache-Control' => 'public, max-age=604800' } > PiyoUploader.new.fog_attributes #=> { 'Cache-Control' => 'no-cache' }