Django2.2をGAE, Cloud SQL環境にデプロイ

本記事ではDjango2.2をGAE、Cloud SQLを使った環境にデプロイする手順を説明してきます。

前準備

以下を前準備として完了している前提で話を進めます。

  • Djangoアプリを作成済み
  • GAEへのデプロイは完了(もしくは完了できる)

GAEへのデプロイは以下の記事を参考にしてみてください。

Django2.2をGAEにデプロイ

GCP側の準備

Cloud SQL インスタンスを立ち上げる

まずGCP側の準備としてCloudSQLインスタンスを立ち上げる必要があります。

ナビゲーションメニュー ⇨ SQL ⇨ インスタンスの作成 ⇨ MySQLを選択

下記のように入力し、「作成」ボタンをクリック。

ユーザの作成

作成したインスタンスをクリックし、ユーザータブを開きます。

ここではユーザーの作成を行って行きます。

「ユーザーアカウントを作成」をクリックし、

ユーザー名、パスワードを入力、「全てのホストを許可する」を選択する。

ユーザー名とパスワードは後で入力するので、記憶するかメモを取っておきましょう。

今回は「devuser」、「devpass」を入力。

「作成」ボタンをクリックすればユーザーの作成が完了です。

データベースの作成

次はデータベースタブを開きます。

「データベースを作成」をクリック。

「データベース名」を入力し、「作成」をクリック。

ここでは、「gae_django_db」を入力しました。

クライアント側の準備

次はクライアントPC側での設定を行って行きます。

Cloud SQL Proxy

Cloud SQLを使った環境にデプロイするには、まずローカルからCloud SQLに繋いでmigrateをする必要があります。

ローカルからCloud SQLに繋ぐのに必要なのがCloud SQL Proxyになりますので、準備して行きましょう。

以下を参考にしながらインストールして行きます。

Cloud SQL Proxy について

まずは、Cloud SQL Admin APIを有効化して行きます。

これは各プロジェクトからCloudSQLに繋ぐために必要になります。

次はCloud SQL Proxyのインストールです。 場所はDjangoプロジェクトのディレクトリと同じ階層にします。

curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64

次に実行できるように権限を与えます。

chmod +x cloud_sql_proxy
ls
Pipfile     Pipfile.lock    cloud_sql_proxy gae_django

ローカルで動作確認をして行きます。

cloud_sql_proxyを動かすには以下のコマンドを入力します。

./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:3306

INSTANCE_CONNECTION_NAMEとは、 CloudSQLのインスタンスの詳細画面の「インスタンス接続名」が該当します。

動かしてみましょう。

./cloud_sql_proxy -instances=gae-django-253212:asia-northeast1:gae-django-sql=tcp:3306

2019/09/22 20:25:50 Rlimits for file descriptors set to {&{8500 9223372036854775807}}
2019/09/22 20:25:51 Listening on 127.0.0.1:3306 for gae-django-253212:asia-northeast1:gae-django-sql
2019/09/22 20:25:51 Ready for new connections

もう1つターミナルを立ち上げて、以下を入力。

mysql -u <USERNAME> -p --host 127.0.0.1

USERNAMEは先ほどユーザーを作成した時に入力した、ユーザー名を入力。

パスワードを聞かれますが、これもユーザー作成時に入力したパスワードを入力します。

mysql -u devuser -p --host 127.0.0.1

Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 499
Server version: 5.7.14-google-log (Google)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

以下を入力してみて、作成したDBが表示されるのを確認しましょう。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| gae_django_db      |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

これでローカルからCloud SQLに繋げることができるようになりました。

migrate

次はCloud SQLにmigrateをして行きます。

そのためにsettings.pyを修正して行きます。


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'USER': 'devuser',
        'PASSWORD': 'devpass',
        'NAME': 'gae_django_db',
        'PORT': '3306'
    }
}

以下が設定内容になります。

  • ENGINE:django.db.backends.mysql
  • HOST:127.0.0.1
  • USER:作成したユーザーのユーザー名
  • PASSWORD:作成したユーザーのパスワード
  • NAME:作成したデータベース名
  • PORT:3306

次にDjangoでmysqlを使うためのドライバをインストールして行きます。

pipenv install mysqlclient

requirements.txtも更新して行きます。

pipenv lock -r > requirements.txt

以上で準備が終わりましたので、migrateして行きます。

cloued-sql-proxyが動いていることを確認して、 以下のコマンドを入力します。

pipenv run python manage.py migrate

これで無事にmigrateができました。

デプロイ

ローカルでCloud SQLに繋いでmigrateができましたので、

最後にGAE上でもCloud SQLに繋いだ状態にしたいため、そのための設定を行って行きます。

環境変数

まずは環境変数を設定して行きます。

先ほどのユーザー名やパスワードを直接書くことはセキュリティ上よくないので、外部ファイルで管理し、app.yamlで外部ファイルを読み込むということをして行きます。

runtime: python37
entrypoint: gunicorn -b :$PORT gae_django.wsgi:application

includes:
    - secret.yaml

handlers:
    - url: /static
      static_dir: staticfiles/
    - url: .*
      script: auto

includesでsecret.yamlを追加しています。

次にsecret.yamlを追加して行きます。

env_variables:
    DB_PASSWORD: 'devpass'
    DB_USER: 'devuser'
    DB_HOST: '/cloudsql/gae-django-253212:asia-northeast1:gae-django-sql'
    DB_NAME: 'gae_django_db'

次にsettings.pyを編集し、環境変数から値を取得するようにします。

if os.getenv('GAE_APPLICATION', None):
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': os.getenv('DB_HOST'),
            'USER': os.getenv('DB_USER'),
            'PASSWORD': os.getenv('DB_PASSWORD'),
            'NAME': os.getenv('DB_NAME'),
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.jotin(BASE_DIR, 'db.sqlite3'),
        }
    }

元々あったDATABASESの部分を上記に置き換えます。

簡単に説明すると、GAE_APPLICATIONという環境変数はGAE上に設定されています。

なので、デプロイ先では上のmysqlのDATABASESが設定され、 ローカルでは下のsqlite3のDATABASESが設定されます。

また、DATABASESの設定もローカルからcloud-sql-proxyを使って接続した時とは異なります。

  • HOST:127.0.0.1 ⇨ インスタンス接続名
  • PORT:3306 ⇨ 削除

デプロイ確認

それではデプロイを行って行きます。

gcloud app deploy --project=gae-django-253212

以下のコマンドで動作確認をしましょう。

gcloud app browse --project=gae-django-253212

最初はテーブルにレコードが入っていないので、createボタンでデータを作成してみます。

無事にデータ作成から取得までできていることが分かります。