🤖

StrapiでS3アップロード・CloudFrontを利用する場合の設定方法

2023/03/13に公開

はじめに

コーポレートサイトのHeadlessCMSの検証をしていた時、Strapiの情報が少なく、S3+CloudFront化するのに少し手間取ったので、備忘録として残しておきます。

動作を確認したのは以下のライブラリです。
https://www.npmjs.com/package/@liashchynskyi/strapi-provider-upload-s3-cloudfront

設定は、URLのREADMEに載っているだけのものでは不十分で、ベースとなっているライブラリのmiddleware.jsの設定や、S3の設定も必要となる。
https://www.npmjs.com/package/@strapi/provider-upload-aws-s3

前提条件

  • Strapiは設置済みであること
  • S3は作成済み
  • CloudFrontとS3の疎通は確認済み

アプリケーション別に必要なアクション

Strapi

yarn, またはnpm@liashchynskyi/strapi-provider-upload-s3-cloudfrontをインストールする

以下を実行する

npm install @liashchynskyi/strapi-provider-upload-s3-cloudfront
# or
yarn add @liashchynskyi/strapi-provider-upload-s3-cloudfront

./config/plugin.js に設定を追加する

ライブラリのREADMEに従って、./config/plugin.jsに以下を設定する

export default ({ env }) => ({
  upload: {
    config: {
      provider: '@liashchynskyi/strapi-provider-upload-s3-cloudfront',
      providerOptions: {
        credentials: {
          accessKeyId: env('AWS_ACCESS_KEY_ID'),
          secretAccessKey: env('AWS_SECRET_ACCESS_KEY'),
        },
        region: env('AWS_S3_BUCKET_LOCATION'),
        bucket: env('AWS_S3_BUCKET_PREFIX'),
        cdn: env('AWS_CLOUDFRONT_DOMAIN'),
      },
    },
  },
});

.envにplugin.jsにある環境変数を設定する

AWS_ACCESS_KEY_ID=XXXXX
AWS_ACCESS_SECRET=XXXXXX
AWS_REGION=ap-northeast-1
AWS_BUCKET=your-strapi-image-backet
AWS_CLOUDFRONT_DOMAIN=https://yourstrapicdn.cloudfront.net

AWS_CLOUDFRONT_DOMAINは、「ドメイン」とあるが、https://が必要なので注意!

./config/middleware.js に設定を追加する

元ライブラリのREADMEを参考に以下を./config/middlewares.jsに追加する

module.exports = [
  // ...
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': [
            "'self'",
            'data:',
            'blob:',
            'dl.airtable.com',
            'yourBucketName.s3.yourRegion.amazonaws.com',
	    'yourstrapicdn.cloudfront.net'
          ],
          'media-src': [
            "'self'",
            'data:',
            'blob:',
            'dl.airtable.com',
            'yourBucketName.s3.yourRegion.amazonaws.com',
	    'yourstrapicdn.cloudfront.net'
          ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  // ...
];

S3

S3のACLを有効にする

もし有効にしていない場合は、マネジメントコンソールのS3で対象化けとを選び、アクセス許可 -> オブジェクト所有者 の欄で有効にする

Cross-Origin Resource Sharing (CORS)に、利用するIPまたはドメインを追加する

元ライブラリのREADMEを参考に以下をアクセス許可 -> Cross-Origin Resource Sharing (CORS)に追加する

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET"],
    "AllowedOrigins": ["YOUR STRAPI URL"],
    "ExposeHeaders": [],
    "MaxAgeSeconds": 3000
  }
]

ブロックパブリックアクセス (バケット設定)を新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックするのみ有効にする

ブロックパブリックアクセス (バケット設定)を以下のように設定する

動作確認

Strapiにアクセスし、Media Libraryで問題なくアップロードされることを確認してください。
もしうまくいかない時は、どこかの設定が漏れているはずなので、サーバログを確認しながら対応していきましょう。

注意点

CloudFrontのENV部分をうっかりHTTPSを抜いて設定した場合、画像が出ません。そこでENVを書き直しても画像は出ませんが、それは正しい動作です。
これは、画像URLは動的に作られておらず、アップロードされた時点で作成され、固定されているからです。

なので、失敗した画像は削除し、新たに画像をアップロードすれば問題なく出るようになります。

Discussion