質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.23%

Djangoで作成したアプリの静的ファイルをAWSのCloudFrontを使って配信したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 507

前提・実現したいこと

Djangoで作成したアプリの静的ファイルをAWSのCloudFrontから配信したいのですが、上手くいきません。

現状

django-storages, boto3を使用してS3からdjangoアプリの静的ファイルを配信する事は問題なく出来ています。
また、CloudFrontのディストリビューションも問題なく作成出来ています。

発生している問題・エラーメッセージ

CloudFrontから配信してほしい静的ファイルが配信されません。S3からそのまま配信されてしまいます。

該当のソースコード

djangoのsettings.pyファイル

# AWS設定
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')

# スタティックファイル(S3)の設定
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_STORAGE_BUCKET_NAME = 'hogehoge-fuga'
AWS_DEFAULT_ACL = None

CloudFrontの設定

CloudFrontの設定1
CloudFrontの設定2
CloudFrontの設定3
イメージ説明
イメージ説明
イメージ説明
イメージ説明

S3のバケットポリシーの設定

該当のバケットには何も書かれていませんでした。
S3のバケットポリシーの設定

SSL証明書

us-east-1なのでバージニア北部で取得出来ていると思います。
イメージ説明

補足情報

おそらくsettings.pyに何か設定が必要なのではと思うのですが、よくわかりませんでした。
かなり初歩的なところでつまづいている気がします。ご教示いただけたら幸いです。

※追記
1)CloudFrontでは自ドメインから配信したいので、そのための設定(CNames)をCloudFrontとroute53でしてあります。
2)CloudFrontのSSL証明書はCertificate Managerを使って取得しております。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yu_1985

    2019/12/02 12:36

    CloudFrontの設定とバケットポリシーはどうなっていますか?

    キャンセル

  • yasuhiro_tera

    2019/12/02 16:00

    ご質問ありがとうございます。追記しました。どうぞよろしくお願います。

    キャンセル

  • nurari

    2019/12/05 23:42

    > CloudFrontから配信してほしい静的ファイルが配信されません。S3からそのまま配信されてしまいます。

    これは何を見てそう判断されましたか?
    また、Django生成されたページ内の静的ファイルのURLは***.tokyoのドメインでしょうか?

    キャンセル

  • yasuhiro_tera

    2019/12/06 02:32 編集

    nurariさん >
    ご質問ありがとうございます。単純にデプロイされたサービスの静的ファイルから配信される画像を新しいタブで開いてみて、その画像のURLが以下のようにS3のものになっていたことから判断しました。
    <バケット名.s3.amazonaws.com/ディレクトリ名/hoge.jp>

    また、Chromeのデベロッパーツールで検証ボタンからCSSの配信元を見てみても以下のようにS3からになっていました。
    <link href="https://バケット名.s3.amazonaws.com:443/css/style.css>

    > また、Django生成されたページ内の静的ファイルのURLは***.tokyoのドメインでしょうか?
    上記の通りURLに含まれているのはバケット名であり、上記のドメインの***の部分はありません。

    また、上に掲示したCloudFrontの設定の画像の1枚目にあります黒塗りになっている「Alternate Domain Names (CNAMEs)」では、通常のドメインと区別出来るように、サブドメインとして頭に「static」を付けてstatic.domain名.tokyoとしておりますが、ここで付けたドメイン名が静的ファイルのURLに含まれていないのもそう判断したポイントの一つです。

    キャンセル

回答 2

+1

その画像のURLが以下のようにS3のものになっていたことから判断しました。
<バケット名.s3.amazonaws.com/ディレクトリ名/hoge.jp>

ご確認ありがとうございます。
S3へのリンクが生成されているということでDjango側の設定の問題っぽいですね。

settings.pyに下記の内容を追記するといかがでしょうか?

AWS_S3_ENDPOINT_URL = "https://static.***.tokyo/"
AWS_S3_REGION_NAME = "<バケットを作成したリージョン>"

https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html

AWS_S3_ENDPOINT_URL (optional: default is None, boto3 only)
Custom S3 URL to use when connecting to S3, including scheme. Overrides AWS_S3_REGION_NAME and AWS_S3_USE_SSL. To avoid AuthorizationQueryParametersError error, AWS_S3_REGION_NAME should also be set.

まずは上記設定を実施し、Djangoから生成されたURLが https://static.***.tokyo/*** に変わるかをお試しください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/06 21:26

    nurariさん

    ご回答いただきありがとうございました。ご指摘いただいたsettings.pyの内容を追記し、再度デプロイ、キャッシュクリア(Command + Shift + R)でスーパーリロードしても以前と同じS3からの配信先しか表示されませんでした。

    AWSのマネジメントコンソール上のCloudFrontの画面からCache Statistics ReportsやCloudFront Popular Objects Reportなどいくつかのレポートを見れることに気づき、上記「CloudFrontの設定」欄に画像を追加しました。40X系のエラーで全て弾かれてしまっているように見えますが、これも思い当たる節がありません汗。

    何度も申し訳ありませんが、何かご存知のことがあればご教示いただければ幸いです。
    よろしくお願いします。

    キャンセル

  • 2019/12/06 22:10

    > 同じS3からの配信先しか表示されませんでした。
    承知しました。それでは、先に追記した内容を消した上で、下記の内容を追記するとどうでしょうか。

    AWS_S3_CUSTOM_DOMAIN = 'static.xxx.tokyo'

    うっかり見落としていたのですが、まさにCloudFrontをCDNとして使用するケースで設定するパラメータとして、公式のドキュメントに記載されています。
    https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#cloudfront

    > 40X系のエラーで全て弾かれてしまっているように見えますが、
    おそらく自動巡回のBotか何かかと思いますが、ファイル名は見覚えのないものでしょうか。

    キャンセル

  • 2019/12/07 17:13 編集

    ご返答ありがとうございました。

    AWS_S3_CUSTOM_DOMAIN = 'static.xxx.tokyo'と追記することで、Chromeのデベロッパーツールで検証してみたところCSSの配信元が無事に<href="https://static.ドメイン名.tokyo/css/style.css">になっていました。

    ところが、今度はCSSを含むそれらの静的ファイルが全く効いていない状況です。

    試しにこのCSSのURLに直接アクセスしてみると、

    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>hogehoge</RequestId>
    <HostId>
    fugafuga=
    </HostId>
    </Error>

    とXML形式(?)の表示が出てしまいます。他の静的ファイルのURLにアクセスしてみてもこれと全く同じ権限系?のエラーでした。

    キャンセル

check解決した方法

0

CloudFrontのオリジンとなるS3には、「REST API エンドポイント」タイプと「静的ウェブサイトエンドポイント」の2つのタイプがあるようでして、まず自分が作ったものはそのどちらなのかを判断しました。

その上で、以下に書かれている内容にしたがって、
AWS公式ドキュメント

アクセス権限 > バケットポリシー で全てのプリンシパルを対象にリソースのgetを許可するようなポリシーを追加したところ、CloudFrontとの疎通が確認できました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる