PythonMania

普段はロボットとAIを組み合わせて色々作ってます。Python関係以外も色々投稿していくと思います。

【Django】Google App EngineにDjangoアプリをデプロイしてみる【追記】

f:id:mizuhiki0111:20190430175940p:plain





前回の記事でDjangoアプリをGoogla App Engineにデプロイする流れをまとめましたが、前回の記事では色々と不十分なところがあったので

追記します。すみません。。。笑



前回の記事が以下になりますが、基本的には今回の記事を参考にしてもらえれば幸いです。

www.pythonmania.work





①Python環境の作成


公式HPよりPythonインストーラをダウンロードし、インストールします。
インストールする際には必ず [PATH に Python を追加]をチェックしてください。

www.python.org


今回はPython3系をインストールしました。


インストールが完了したら、コンソールを立ち上げ仮想環境構築用のモジュールをインストールします。

pip install --upgrade virtualenv

次に仮想環境を作成します。

virtualenv --python "python.exeへのフルパス" 仮想環境名

仮想環境が作成されたら、作成した仮想環境を有効化します。

\仮想環境名\Scripts\activate

ここまででPython環境・仮想環境の構築が完了しました。この作業を行うことで、ほかのプロジェクトに影響を受けずにアプリ開発を行うことができます。









②Cloud SDKのインストール

公式HPよりCloud SDKをインストールしてきます。


cloud.google.com



またPython用Cloud クライアントライブラリもインストールしておきます。

pip install --upgrade google-cloud-storage

また以下のコマンドを使ってクラウドのインスタンスを初期化しておきます

gcloud init

上記コマンドを入力すると色々表示されますが、GCPで作成したプロジェクトを選択し、使用するアカウントを選べばOKだと思います。



③Cloud SQL Proxyのダウンロード

以下のURLを右クリックして「名前つけてリンク先を保存」します。

名前は「cloud_sql_proxy」にしておいてください

https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe




④Cloud SQL インスタンスの作成



以下のリンク参照しながらCloud SQLの第2世代インスタンスを作成していきます

cloud.google.com




1. インスタンス作成をクリック

2.「MySQL」を選択して「次へ」

3.「第2世代を選択」をクリック

4. 名前・パスワードをクリック

5. インスタンスのリージョン設定(プロジェクトと一緒でOK,東京なら「asia-northeast1」

6. ゾーンはそのままでOK




次にコンソールでの作業に移ります

コンソールで以下を実行

gcloud sql instances describe [YOUR_INSTANCE_NAME]


出力された [CONNECTION_NAME] をメモしておく

[CONNECTION_NAME] の値は、[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] の形式になっています






次にCloudSQLProxyをインストールしたディレクトリに移動し

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


を実行


[YOUR_INSTANCE_CONNECTION_NAME]は先程メモした[CONNECTION_NAME]の値に書き換え

※An attempt was made to access a socket in a way forbidden by its access permissions.みたいなエラーは、3306のポートへ外部からアクセスできないために起こります。
 使用するポート番号(3306)を開放する必要があります。



「Ready for new connections」と出てきたら、このコンソールはローカルでアプリのテストが完了するまでそのままにしておく

→ここからはもう一つコンソールを開いてそちらで作業していきます


⑤Djangoアプリの作成


別のコンソールを開いたらまず仮想環境の有効化を行います。

.\環境名\Scripts\activate

Djangoのインストール

pip install django==2.1

※Djnago2.2~ではpymysqlをインストールした際にエラーが発生してしましました。
 Djjango2.1系をインストールしてください


その他必要なライブラリのインストール

pip install django-storages
pip install pymysql


プロジェクトの作成

django-admin startproject プロジェクト名

アプリの作成

cd プロジェクト名
python manage.py startapp アプリ名


アプリ作成まで完了したら

python manage.py runserver

で試しに起動してみます。






⑥init.pyの編集

プロジェクトのinit.pyに以下を追記します。

#init.py
import pymysql  # 追記

pymysql.install_as_MySQLdb() #追記


⑦app.yamlの作成


manage.pyと同じ階層に「app.yaml」を作成し内容を以下の様に作成します。

runtime: python37
entrypoint: gunicorn -b :$PORT プロジェクト名.wsgi:application

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


このファイルはAppEngineの構成ファイルを設定するもので、参照するwsgiファイルやstaticディレクトリなどを記載しておきます。


「プロジェクト名」のところはDjangoで作成したプロジェクトの名前に変更しておいてください。







⑧サービスアカウント・ユーザー・データベースの作成


今度はGCPのサイト上で操作していきます。


まずAPIにアクセスするためのサービスアカウントを作成します。




メニューの「APIとサービス」「認証情報の作成」をクリックします。


次に青色の「認証情報を作成」ボタンをクリックし、「サービスアカウントの作成」をクリックします。


「新しいサービスアカウント」→Jsonを選択し、作成をするとサービスアカウントキー情報が記載された

JSONファイルがダウンロードできると思います。


※なお「役割」を選択するプルダウンが表示された場合には「ストレージ」→「ストレージ管理者」として置いてください。
そうしないと後でDBにアクセスするときにエラーが発生してしまいます。



これをmanage.pyと同じディレクトリに保存しておいてください。



次に、先ほど作成したCloudSQLの第二世代インスタンスにユーザーとデータベースを作成していきます。



まずメニューから「SQL」を選択します。

インスタンスの名前をクリックし、「ユーザー」タブをクリックします。


「ユーザーアカウントの作成」から「ユーザー名」「パスワード」を入力し、新規ユーザーを作成してください。




同様にデータべースも作成していきます。



「データベース」タブに移行し、「データベースを作成」ボタンから新規データベースを作成してください。



⑨バケットの作成

バケットはクラウド上に画像などのファイルを保存しておく場所になります。


今回の場合はDjangoアプリのstaticディレクトリ内のファイルややmediaディレクトリなどをここで管理する形となります。


メニューから「Storage」を選択して、画面上部の「バケットを作成」から新規バケットを作成します。


ここでも役割を選択するプルダウンが表示された場合にはStorage管理者としておいてください。






⑩setting.pyの編集

setting.pyを順番に編集していきます。


ライブラリのインポート

from google.cloud import storage

INSTALLED_APPSの追加

    'mysite',
    'storages',  #追加
    'bootstrap4',
    'django_cleanup',
    'widget_tweaks',
    'bootstrap_datepicker_plus',
    'accounts.apps.AccountsConfig',


データベース設定の記載部分

if os.getenv('GAE_APPLICATION', None):
    # Running on production App Engine, so connect to Google Cloud SQL using
    # the unix socket at /cloudsql/<your-cloudsql-connection string>
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '/cloudsql/"[YOUR_INSTANCE_CONNECTION_NAME]"',
            'USER': 'データベースのユーザー名",
            'PASSWORD': 'データベースのパスワード',
            'NAME': '作成したデータベース名',
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': 'localhost',
            'PORT': '3306',
            'NAME': 'データベース名(ローカル)',
            'USER': 'root',
            'PASSWORD': 'データベースのパスワード',
        }
    }

データベースの設定記載部分は、上段にクラウドSQLの情報、下段にローカルのデータベースの情報を記載しておきます。


その他バケットやサービスアカウントの設定などを記載していきます。

STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

ALLOWED_HOSTS = ["インスタンス名.appspot.com","127.0.0.1",'localhost']

from google.oauth2 import service_account
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
    'サービスアカウントキー(jsonファイル)へのパス(同階層であればファイル名を書けばOK)'
)

DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
STATICFILES_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = '⑨で作成したバケット名'
GS_PROJECT_ID = 'プロジェクトID'


これでsetting.pyの変更は完了です。















無事に起動ができたら、以下のコマンドでGAEへデプロイすることができます。

requirements.txtの作成

pip freeze > requirements.txt

※requirements.txtを作成したら、追加で「gunicorn==19.9.0」を記載しておきます。

gcloud app deploy