GAE standard環境にて Python3 + Djangoでサーバを構築する

どうも。初記事です。緊張します。

# GAE standard環境でpython3が使えるようになったってよ!

長らくGAEのstandard環境ではpython2しか使えませんでした。
python3にするにはflexible環境を用いなければならなかったのですが、2018年7月にpython3対応しました!  ヤッターーーー!
https://cloudplatform.googleblog.com/2018/07/bringing-the-best-of-serverless-to-you.html

それの何がすごいん? という方はこちら
https://qiita.com/mokrai/items/77f44551b8d219cfb370

今回はそのpython3を使ってDjangoを動かすところまでやります。
構築完了後にうろ覚えで書いているので抜けているところが多分あります。ご容赦を。

# 1. 事前準備 

## 1-1. GAEセットアップ

python2 standard環境でのDjango構築方法は公式ページに記載されているので見に行きます。
事前準備はpython3でも変わらないので、公式に従いながらチェックボックスを埋めていきましょう。
Google Cloud SQL API を有効にするところまでやってください。
https://cloud.google.com/python/django/appengine?hl=ja

**基本的な流れはpython2と同じです。迷ったら公式だ!**

## 1-2. python開発環境構築
もちろんpythonもインストールしておきましょう。これも公式が書いてくれているよ!
https://cloud.google.com/python/setup?hl=ja

## 1-3. サンプルダウンロード

[「アプリのダウンロードと実行」](https://cloud.google.com/python/django/appengine?hl=ja#download_and_run_the_app)にて、サンプルが取得できるとあります。
取得して見ましょう。リポジトリをcloneじゃ!

```
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
```

...おっ!

flexibleとstandardと並んで、python3のサンプルアプリもある! (他はpython2のサンプルアプリダヨ)
どれどれ...

<img width="407" alt="スクリーンショット 2018-10-11 11.18.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/164351/1ed1a789-54cd-4a5e-936d-31bcc414a4f6.png">

**すくな!!**
standard(python2)はいっぱいあるのに...
hello_worldの中身を見たらflaskの最小構造だった。でもリリースしたばかりだ、仕方ない。

今回はこのhello_worldと、python2のDjangoのサンプルアプリを参考にして構築してみる。

`/python-docs-samples/appengine/standard_python37/hello_world`
`/python-docs-samples/appengine/standard/django`

# 2. Djangoの新規アプリを作成する
余計な不純物が混ざらないようにするため、DjangoをインストールしてDjangoのコマンドからアプリ作成

```
pip install Django==2.1.1
django-admin.py startproject my_app ./
```

# 3. ファイル構成

サンプルアプリ `/python-docs-samples/appengine/standard/django` から
必要なファイルをコピーしたりなどして、最終的な必要ファイル構成は以下に。

```
├── [app_name]
│   ├── settings.py
│   ├── urls.py
│   ├── views.py
│   └── wsgi.py
├── app.yaml
├── manage.py
└── requirements.txt
```

サンプルアプリから取ってくるファイルは以下。

 - settings.py ・・・ DB(cloud sql)に接続するための情報
 - app.yaml ・・・ GAEにデプロイするための情報
 - requirements.txt ・・・　必要なpythonライブラリ情報

## 3-1. app.yaml

```yml
runtime: python37
entrypoint: gunicorn -b :$PORT [app_name].wsgi:application

handlers:
- url: /static
  static_dir: static/
- url: .*
  script: [app_name].wsgi.application
```

### 解説
 - handlersは従来のまま。
 - `runtime` を `python27` => `python37` に変更。
 - api_version, threadsafe, skip_filesはpython37では対応してないため軒並み削除。(skip_filesはちょっと例外あり)  
これがあるとdeployエラーが出る。  
公式のリファレンスをみるとpython37のruntimeではサポートしてないよ! って書いてあるね。  
https://cloud.google.com/appengine/docs/standard/python3/config/appref
 - entrypointを記述する。この設定を見てGAEがアプリの起動ポイントを判断します  
なにそれ? 詳しく って方はこちら。  
https://cloud.google.com/appengine/docs/flexible/python/runtime?hl=ja#application_startup

## 3-2. requirements.txt

```
PyMySQL
Django>=2.1.1
gunicorn
```

### 変更点

 - gunicornの追加  
`app.yaml` で追加したentrypointの設定のため必要です。無いとデプロイ時にエラーとなります。
 - Djangoのバージョン指定  
現在ダウンロードした最新版以上のバージョンを指定しています。


## 3-3. settings.py

djangoのコマンドでアプリを作成するとデータベース接続がsqliteになってます。
もちろんcloud sqlにしましょう。
sqliteを削除して、setting.pyを公式通りに変更しましょう。
https://cloud.google.com/python/django/appengine?hl=ja#understanding_the_code

**ここからはほとんど[公式ページ](https://cloud.google.com/python/django/appengine?hl=ja)を参考にすればOKですが、一応簡単に書いておきます。**

# 4. ローカルで実行を確認

```
virtualenv env
source env/bin/activate
manage.py migrate
python manage.py runserver
```

終了時

```
deactivate
```
公式:
https://cloud.google.com/python/django/appengine?hl=ja#run_the_app_on_your_local_computer

# 5. GAEにdeploy

```
gcloud auth login
python manage.py collectstatic
gcloud app deploy
```

公式:
https://cloud.google.com/python/django/appengine?hl=ja#deploy_the_app_to_the_app_engine_standard_environment