ポンコツ.log

ひよっこエンジニアのちょっとしたメモ。主に備忘録。たまに雑記。

【AWS】CloudFrontで特定ファイルをキャッシュしないようにする

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' }