【Django】GoogleCloudStorageの設定方法

【Django】GoogleCloudStorageの設定方法

こんばんはエンジニアの眠れない夜です。

今回はDjangoで Google Cloud Storage を設定する方法をご紹介します。

django-storagesのドキュメントを読めばそのままなのですが、認証の辺りをきちんと理解できておらずハマってしまいました…

この記事を読んでいる方はサックと設定ができるようにお役に立てれば幸いです。

全体的な流れはこの3ステップです。

  1. Google Cloud サービスアカウントを作成
  2. アカウントとストレージ(バケット)と紐付け
  3. Django のセッティングファイルに設定を書く

それでは順番に設定していきます。

Google Cloud サービスアカウントを作成

まずはGoogleCloudを開いて、サービスアカウントを作成します。

add-service-account-key

ここで作成する名前はアプリケーションやプロジェクト名にすると分かりやすいです。

役割は「ストレージ管理者」や「ストレージのオブジェクト管理者・編集者」など必要に応じて権限を設定すればOKです。

make-service-account-key

設定が終わると JSON ファイル をダウンロードできます。このファイルは今作成したアカウントでストレージにアクセスするために必要になります。

今作成したアカウントのメールアドレスを次のステップで使うのでサービスアカウントの一覧で確認して、どこかにコピペしておきます。

バケット非公開なので一般公開する方法はこちらを確認してください。

※ サービスアカウントの作成方法の説明はこちらの記事の方が丁寧です。

GoogleCloudStorageでPythonからファイルをやりとりする方法

アカウントとストレージ(バケット)と紐付け

続いてストレージからバケットを作成します。

google-cloud-storages-make-baket-1

バケットを作成したら「権限」の設定に移ります。

「メンバーを追加」をクリックするとメールアドレスを入れる欄が出てくるので先程メモしたサービスアカウントのメールアドレスを入力します。アカウントの権限は「ストレージ管理者」など適宜設定を行ってください。google-cloud-storages-make-baket

これで作成したアカウントがこのバケットに読み書きできるようになりました。

バケット名とプロジェクト名を次のステップで使うので適当にコピペしておきます。

プロジェクト名はここから確認できます。

google-cloud-project-name

Djangoのセッティングファイルに設定を書く

まずはdjango-storagesgoogle-cloud-storageをインストールします。

pip install django-storages google-cloud-storage

※ google-cloud-storage 以外の似たようなモジュールが入っているとfrom google.***で違うモジュールを参照してしまいエラーになることがあります。その場合は上記以外のgoogleから始まるモジュールをアンインストールして動作確認をすると解決します。

続いて Django のsetting.pyで設定を行います。settings.pyには次ように書きます。

your-xxx の部分は先程コピペした情報やJSONファイルのパスを設定すればOKです。

※ ターミナルにJSONファイルをドラッグすると絶対パスを取得できます。
※ 開発環境と本番環境でパスは異なるので注意。

これで設定は終わりです。とても簡単ですね!

その他、詳しい設定はこちらのdjango-storagesの公式ドキュメントを参考にしてください。

Cloud Storageの動作確認

後は python manage.py collectstatic を実行するとバケットにstaticフォルダの中身がアップロードされます。

ファイル数にもよりますが、時間がかかるので気長に待ちましょう。

バケットを更新するとファイルやフォルダーが少しずつ増えているのを確認できます。

クラウドストレージにstaticファイルをアップロード

※ あまりにも遅いのでブラウザからドラッグしてみましたが、こちらもかなり時間がかかります。

gsutil コマンドでファイルをアップロード

gsutilコマンドを使ってアップロードすると良さそうです。gsutilコマンドはクラウドストレージにファイルをアップロードしたりファイルの権限を変更するのに利用するコマンドです。

詳しい使い方はこちら

staticフォルダーをクラウドストレージにまるごとアップロードするには↓このコマンドを実行します。

gsutil -m cp -rZ  /path/to/static/css/  gs://your-bucket-name/
gsutil -m cp -rZ  /path/to/static/js/  gs://your-bucket-name/

↑こんな感じでstaticファイルの中のフォルダを指定してアップロードしていきます。

コマンド1つでstaticフォルダの中身を全部アップロードしたいところなのですが↓このように指定すると

gsutil -m cp -rZ  /path/to/static/  gs://your-bucket-name/

バケットの直下にstaticフォルダが作成されて、その中にフォルダーやファイルがコピーされてしまいます。何かいい方法があればコメントをいただけると嬉しいです。

gsutil コマンドの説明

コマンドとオプションの意味を簡単に添えておきます。

  • -m 処理速度が速くなるオプション
  • cp コピー
  • -r ディレクトリーをコピーする時に使う
  • -Z gzip化されたファイルを配信できるようにする

最後のZが重要で、これを設定していないとページスピードインサイトで驚くほど低いスコアを叩き出します。

スコア:モバイル 3、パソコン 50

スコア:モバイル 50、パソコン 85

くらい変化したのでZは忘れずに指定しておきたいオプションです。

pagespeed:insights

CloudStorageでオブジェクトを更新する方法

先ほど紹介したオプションの他に-n というオプションもあります。

-n は更新されたファイルとアップロードされていないファイルのみをアップロードするオプションです。

次回以降クラウドストレージを更新する時に便利なオプションです。

【使用例】

gsutil -m cp -rnZ  /path/to/static/js/  gs://your-bucket-name/

-n は少し注意が必要なのでこの注意書きご確認ください。

This option will perform an additional GET request to check if an item exists before attempting to upload the data. This will save retransmitting data, but the additional HTTP requests may make small object transfers slower and more expensive.

このオプションは、データをアップロードする前にアイテムが存在するかどうかを確認する追加のGETリクエストを実行します。これにより、データの再送信が節約されますが、追加のHTTPリクエストにより、小さなオブジェクトの転送が遅くなり、コストが高くなる場合があります。

ドキュメント cp

転送量を節約できる代わりにリクエストが増え、遅く、コストが高くなるようです。

なので、-n を使うときはバケットまるごとアップデートするのではなくフォルダー単位で必要な範囲に限定して更新を行いましょう。

開発環境と本番環境を使い分ける時の運用方法

Djangoの開発環境と本番環境を使い分ける方法は色々ありますよね。

使っている開発環境のアプリケーションやPythonを仮想環境で動かしているのかDockerを使っているか、他にはDjangoの運用方法など色々あって一概には言えないのですがCloudStorageと開発環境を分ける時の運用方法の一例を載せておきます。

① settings.pyの設定

if DEBUG:
    STATIC_ROOT = os.path.join(BASE_DIR,'static')
    STATIC_URL = '/static/'
else:
    DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
    STATICFILES_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
    GS_BUCKET_NAME = 'MY_BUCKET_NAME'
    GS_PROJECT_ID = 'MY_PROJECT_ID'
    STATIC_URL = 'https://storage.googleapis.com/MY_BUCKET_NAME/'

② 開発環境ではいつもどおりローカルのファイルを使って、本番環境に公開する前に

python manage.py collectstatic

で staticファイルに纏めてCloudStorageを更新します。

③ 更新したstaticファイルをCloudStorageに反映させる

gsutil -m cp -rnZ  /path/to/static/  gs://your-bucket-name/

staticファイルをまるごとアップロードするとさっきの-nの注意書きの通り時間やコストがかかるのでこの時実行するコマンドは適宜変更してください。

まとめ

DjangoでCloudStorageを設定する方法と設定した後に困りそうなところを書いてたらどんどん記事が長くなってしまいました。

簡単に要点だけをおさらいするとDjangoとクラウドストレージを繋ぐ方法はこの3ステップです。

  1. Google Cloud サービスアカウントを作成
  2. アカウントとストレージ(バケット)と紐付け
  3. Django のセッティングファイルに設定を書く

Djangoとクラウドストレージをつないでからファイルをアップロードしたり、オプションの説明がすごく長くなりましたがこのコマンドを使えばだいたい解決します。

  • -m 処理速度が速くなるオプション
  • cp コピー
  • -r ディレクトリーをコピーする時に使う
  • -Z gzip化されたファイルを配信できるようにする
  • -n 更新されたファイルのみをアップロード
gsutil -m cp -rnZ  /path/to/static/  gs://your-bucket-name/

-m だけcpの左側に書くことに注意してください。私は間違って右側に入れてエラーに悩まされました(笑)

長くなりましたがDjangoでCloudStorageを利用する方法は以上です。

最後までご覧頂きありがとうございました。

DjangoとCloudStorageを使う方の参考になりますように(_ _)

おまけ

Googleストレージで使う「バケット」という単語の意味がよくわからなかったのですが、英文のページを見るとBucketsと書いてありました。バケツのことだったんですね。

確かに、アイコンがバケツだ… (゜o゜;

Googleバケット

単数形:Bucket 複数形:Buckets

日本人的にはではどちらでもバケツなんですけどね(;´∀`)

1 Comment

GoogleCloudStorageでPythonからファイルをやりとりする方法 | エンジニアの眠れない夜 へ返信するコメントをキャンセル

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください