くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

GAE+Cloud SQLでDjangoを動かしてみる

DjangoをGAE+Cloud SQL環境で動かしてみたときの備忘録。

基本は、GAEのドキュメントに従えばOK。

注意点/ハマったところ

  • Cloud SQLをローカルでつなぐ時はプロキシツールを実行しておかないといけない
  • settings.pyに習って、各種設定が必要
  • ファイルは書き込むと起動時にエラーになるので、ログとかは抑止しないといけない
  • cron使う場合は、Django側でSSLリダイレクトしてはいけない
    • cronはHTTPでアクセスするが、リダイレクトするとエラーになる
    • 特定のパスのみ許可し、GAEのapp.yaml側でリダイレクトを指定する

GAE+CloudSQLで動かすための変更点

1. settings.pyのDB設定を変更する

# settings.py

# 略...

# Database

# PyMySQLのインストールが必要
import pymysql  # noqa: 402
pymysql.version_info = (1, 4, 6, 'final', 0)  # change mysqlclient version
pymysql.install_as_MySQLdb()

# [START db_setup]
if os.getenv('GAE_APPLICATION', None):
    # GAE上で動いているときの設定
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '/cloudsql/[YOUR-CONNECTION-NAME]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]',
            'NAME': '[YOUR-DATABASE]',
        }
    }
else:
    # ローカルで動いているときの設定。
    # 事前に./cloud_sql_proxyを実行してプロキシ経由でアクセスできるようにする必要がある。
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'NAME': '[YOUR-DATABASE]',
            'USER': '[YOUR-USERNAME]',
            'PASSWORD': '[YOUR-PASSWORD]',
        }
    }
# [END db_setup]

# 略...

# 他にLOGGINGを指定してログファイルを出力している場合は、
# 環境変数を見て、出力しない設定にする必要がある。

2. main.pyの作成

GAEは、main.pyを起点に実行しているため、別途作成する必要がある。

# ~/main.py
from app.wsgi import application
app = application

3. app.yamlの作成

インスタンスなどの設定。他の項目は、以下を参照。
app.yaml 構成ファイル  |  Python 3 の App Engine スタンダード環境  |  Google Cloud

# [START django_app]
runtime: python37

handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
  static_dir: static/

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
  script: auto
# [END django_app]

4. requirements.txtの用意

もしなければ、pipでインストールするパッケージを準備しておく。

$ pip freeze > requirements.txt

準備はこれでOK

デプロイしてみる

マイグレーションを実行する

まずは、ローカルからCloud SQLにアクセスできるようプロキシを起動。
cloud_sql_proxyのインストール方法はここに記載されてる。

$ ./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306

この状態で別のターミナルを開き、マイグレーションを実行。
./cloud_sql_proxyが実行している状態でないといけないので、別ターミナルで実行する。

$ python manage.py makemigrations
$ python manage.py migrate

GAEにデプロイする

# 必要あれば、collectstaticを実行しておく
$ python manage.py collectstatic

# 現在の設定を確認
$ gcloud config list

# デプロイ
$ gcloud app deploy --project sales-manage

これでOK!

GAEのcron.yamlで定期実行する

GAEには定期的にURLを叩ける便利な機能がある。
これを使って定期実行させることができる。  ・cron.yaml を使用したジョブのスケジューリング  |  Python 3 の App Engine スタンダード環境

1. cron.yamlの作成

# cron.yaml
cron:
- description: "daily summary job"
  url: /tasks/summary
  schedule: every 24 hours

2. settings.pyの設定確認

# settings.py
SECURE_SSL_REDIRECT = False

GAEのcronは、HTTPでアクセスされ、リダイレクトされると実行が失敗する。
そのため、SECURE_SSL_REDIRECTがTrueになっていないことを確認し、
設定されていたら、Falseに変更しておく

3. app.yaml

Django側でリダイレクトする処理がないので、GAE側でリダイレクトするように変更する

# [START django_app]
runtime: python37

handlers:
- url: /static
  static_dir: static/

# cronで呼び出されるURLはなにもしないように設定
- url: /tasks/.*
  script: auto

# それ以外のURLは、httpsへリダイレクトするように変更
- url: /.*
  secure: always
  redirect_http_response_code: 301
  script: auto
# [END django_app]

4. cron.yamlのデプロイ

app.yamlの変更後にGAEへデプロイしたら、
cron.yamlもデプロイする。

$ gcloud app deploy cron.yaml

以上!!

参考にしたサイト様