20m61 / Sonotecture

0 stars 0 forks source link

AWS S3とCloudFrontを使用した静的ファイルのホスティング #4

Open 20m61 opened 2 months ago

20m61 commented 2 months ago

Next.jsプロジェクトの静的ファイルや3DモデルなどをS3にアップロードし、CloudFrontを使ってキャッシュおよび配信を行う設定を行います。

  1. AWS S3バケットの作成と静的ファイルのアップロード。
  2. CloudFrontディストリビューションの設定(S3バケットとの連携)。
  3. CDNによる高速配信のための設定最適化。
  4. S3への自動デプロイ設定(CDKやCI/CDを使用)。
20m61 commented 1 month ago

1. Next.jsのスタンドアロンモード設定

まず、Next.jsのプロジェクト設定を調整します。

next.config.mjsの設定

next.config.mjsに以下の設定を追加します。

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone', // スタンドアロンモードを有効化
  distDir: 'build', // ビルドの出力ディレクトリ
  experimental: {
    appDir: true, // App Routerを有効化
  },
};

export default nextConfig;

2. Next.jsアプリケーションのビルド

次に、Next.jsアプリケーションをスタンドアロンモードでビルドします。

yarn build

ビルドが完了すると、buildディレクトリに以下のファイルとディレクトリが生成されます。

3. AWS Lambdaまたは他の環境へのデプロイ

スタンドアロンモードでビルドされたファイルは、Node.jsサーバーとして動作するので、AWS Lambdaや他のサーバーレス環境に簡単にデプロイできます。

AWS CDKを使ったデプロイ

LambdaやS3、CloudFrontを組み合わせてデプロイする場合、以下のような手順を使用します。

  1. CDKのプロジェクトを初期化:

    cdk init app --language typescript
  2. CDKスタックの設定:

    lib/sonotecture-infra-stack.tsを以下のように設定します。

    import * as cdk from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import * as s3 from 'aws-cdk-lib/aws-s3';
    import * as lambda from 'aws-cdk-lib/aws-lambda';
    import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
    import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
    import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
    import * as path from 'path';
    
    export class SonotectureInfraStack extends cdk.Stack {
     constructor(scope: Construct, id: string, props?: cdk.StackProps) {
       super(scope, id, props);
    
       // S3バケット(publicディレクトリ用)
       const bucket = new s3.Bucket(this, 'SonotectureAssetsBucket', {
         versioned: true,
         removalPolicy: cdk.RemovalPolicy.DESTROY,
         autoDeleteObjects: true,
       });
    
       // Lambda関数作成(SSR用)
       const nextJsLambda = new lambda.Function(this, 'SonotectureNextLambda', {
         runtime: lambda.Runtime.NODEJS_18_X,
         handler: 'server.handler',  // LambdaでNext.jsを実行
         code: lambda.Code.fromAsset(path.join(__dirname, '../build/standalone')),  // スタンドアロンモードでビルドされたNext.jsを参照
         memorySize: 1024,
         timeout: cdk.Duration.seconds(30),
       });
    
       // CloudFrontの設定
       const distribution = new cloudfront.Distribution(this, 'SonotectureDistribution', {
         defaultBehavior: {
           origin: new origins.S3Origin(bucket),
           cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED,
         },
         additionalBehaviors: {
           'lambda/*': {
             origin: new origins.HttpOrigin(nextJsLambda.functionArn), // Lambda関数をオリジンとして設定
           },
         },
       });
    
       // S3にpublicディレクトリの静的アセットをデプロイ
       new s3deploy.BucketDeployment(this, 'DeployPublicAssets', {
         sources: [s3deploy.Source.asset('../public')],  // publicディレクトリを指定
         destinationBucket: bucket,
         distribution,
         distributionPaths: ['/*'],  // CloudFrontに即時反映
       });
    
       // LambdaにS3バケットアクセス権限を付与
       bucket.grantReadWrite(nextJsLambda);
     }
    }

    ポイント:

    • Lambda関数: スタンドアロンモードでビルドされたNext.jsを実行するためのLambda関数を作成しています。
    • S3バケット: Next.jsのpublicディレクトリにある静的ファイルをS3にアップロードし、CloudFront経由で配信します。
    • CloudFrontの設定: 静的アセットをS3から配信し、動的コンテンツ(SSR)はLambdaで処理します。

4. CDKでのデプロイ

CDKを使ってデプロイを実行します。

cdk synth
cdk deploy

これで、AWSにNext.jsアプリケーションがデプロイされます。CloudFrontのURLが表示されるので、それを使ってブラウザでアプリケーションを確認できます。

まとめ

これで、Next.jsアプリケーションをスタンドアロンモードでLambdaとS3にデプロイできます。もしデプロイに問題があれば、さらに詳細なサポートも提供できますので、気軽にお知らせください。