静的ファイルの保存と提供

アプリケーションでは、動的リクエストを処理するほか、JavaScript、画像、CSS などの静的ファイルを提供する必要が生じることがよくあります。スタンダード環境のアプリで静的ファイルを提供する方法には、Cloud Storage などの Google Cloud のサービスを使用する、アプリから直接提供する、サードパーティのコンテンツ配信ネットワーク(CDN)を使用する、という選択肢があります。

Google Cloud には無料枠が用意されているため、Google Cloud で静的サイトをホストすると、従来のホスティング プロバイダを利用する場合よりも費用を削減できます。

Cloud Storage からファイルを提供する

Cloud Storage では、動的ウェブアプリの静的アセットをホストできます。アプリから直接提供する代わりに Cloud Storage を使用すると、次のメリットがあります。

  • Cloud Storage は基本的に、コンテンツ配信ネットワークとして機能します。一般公開されているすべてのオブジェクトがデフォルトでグローバル Cloud Storage ネットワークのキャッシュに保存されるため、特別な構成は必要ありません。
  • 静的アセットの提供を Cloud Storage にオフロードすることで、アプリの負荷が軽減されます。静的アセットの数とアクセスの頻度によっては、アプリの実行コストを大幅に削減できる可能性があります。
  • コンテンツにアクセスするための帯域幅の料金は、多くの場合、Cloud Storage を利用すると低くなります。

アセットを Cloud Storage にアップロードするには、gsutil コマンドライン ツールまたは Cloud Storage API を使用します。

Google Cloud クライアント ライブラリは、汎用的な Java 11 / 17 クライアントを Cloud Storage に提供します。これにより、App Engine アプリで Cloud Storage を使用してデータの格納や取得を行うことができます。

Cloud Storage バケットから提供する例

Cloud Storage バケットを作成し、Google Cloud CLI を使用して静的なアセットをアップロードする簡単な例を示します。

  1. バケットを作成します。プロジェクト ID の後にバケットに名前を付けるのは一般的ですが必須ではありません。バケット名はグローバルに一意でなければなりません。

    gsutil mb gs://<your-bucket-name>
    
  2. バケット内のアイテムへの読み取りアクセス権を付与するよう ACL を設定します。

    gsutil defacl set public-read gs://<your-bucket-name>
    
  3. アイテムをバケットにアップロードします。通常は、rsync コマンドを使用すると、最も短時間で簡単にアセットをアップロードして更新できます。cp も使用できます。

    gsutil -m rsync -r ./static gs://<your-bucket-name>/static
    

これで、https://storage.googleapis.com/<your-bucket-name>/static/... を介して静的アセットにアクセスできるようになりました。

カスタム ドメイン名から提供する方法など、Cloud Storage を使用して静的アセットを提供する方法の詳細については、静的ウェブサイトのホスティングをご覧ください。

他の Google Cloud サービスからファイルを提供する

Cloud CDN または他の Google Cloud Storage サービスを使用することもできます。

アプリからファイルを直接提供する

スタンダード環境で Java 11 / 17 の静的ファイルを提供するには、app.yaml ファイル内で static_dir 要素または static_files 要素のいずれかを使用してハンドラを定義します。

静的ファイルや静的ディレクトリの内容は、app.yaml ファイルのスケーリング設定の影響を受けません。静的ファイルまたは静的ディレクトリへのリクエストは、App Engine インフラストラクチャによって直接処理され、アプリケーションの言語ランタイムに到達しません。

静的ファイル ハンドラを構成する

/static URL から ./public ディレクトリが提供されるようにアプリケーションを構成するには、app.yaml ファイル内にハンドラを定義します。

次は、サンプル アプリケーションの ./public ディレクトリの静的ファイルを提供する方法を示しています。このアプリの index.html ページのテンプレートは、ブラウザに main.css ファイルを読み込むよう指示します。次に例を示します。

<link type="text/css" rel="stylesheet" href="/static/css/main.css">

./public ディレクトリは、プロジェクトの app.yaml ファイル内の static_dir 要素に定義されています。

handlers:
  - url: /favicon\.ico
    static_files: favicon.ico
    upload: favicon\.ico

  - url: /static
    static_dir: public

  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

上記の例の handlers セクションでは、次の 3 つの URL パターンが処理されます。

  • /favicon.ico ハンドラは、/favicon.ico 専用のリクエストを、アプリのルート ディレクトリにある favicon.ico という名前のファイルにマッピングします。

  • /static ハンドラは、/static で始まる URL のリクエストをマッピングします。/static で始まる URL のリクエストを App Engine が受け取ると、./public ディレクトリにあるファイルへのパスの残りの部分がマッピングされます。このディレクトリ内に該当するファイルがある場合、そのファイルのコンテンツがクライアントに返されます。

  • /.* ハンドラは他のすべての URL と一致し、それらをアプリに転送します。

URL パスのパターンは app.yaml 内での出現順でテストされます。したがって、静的ファイルのパターンは /.* パターンの前に定義する必要があります。詳細については、app.yaml リファレンスをご覧ください。

Spring Boot アプリで静的ファイルを提供する例

たとえば、Spring Boot アプリの BOOT-INF/classes/static ディレクトリにあるすべての静的ファイルを提供するには、アプリをデプロイする前に次の操作を行います。

  1. アプリのすべてのクラスを含む JAR ファイル(fat JAR)を解凍します。

  2. 次の entrypoint フィールドを app.yaml 構成ファイルに追加します。

     entrypoint: java -noverify BOOT-INF/resources/:BOOT-INF/classes/:BOOT-INF/lib/* com.mycompany.myapp.YOUAPPCLASSNAME
    
  3. 次のハンドラを app.yaml ファイルに追加して、静的リソースを構成します(これは、解凍した fat JAR を使用する場合に必要です)。

      handlers:
      - url: (/.*)
        static_files: BOOT-INF/classes/static\1
        upload: BOOT-INF/classes/static/.*\.(gif|png|jpg|svg|ico|css|js|html)$
        require_matching_file: True
        login: optional
        secure: optional
    

アプリをデプロイします。

サードパーティのコンテンツ配信ネットワークから提供する

外部のサードパーティ CDN を使用して静的ファイルを提供し、動的リクエストをキャッシュに保存することはできますが、その場合、アプリのレイテンシとコストが増える可能性があります。

パフォーマンスを向上させるには、CDN Interconnect をサポートしているサードパーティ CDN を使用してください。