Zappa で Django をデプロイする

記事タイトルとURLをコピーする

はじめに

Python の Web フレームワークである Django を AWS に Zappa を用いてデプロイします。 今回は Amazon Linux 2 上で Guide to using Django with Zappa に沿って進めてみます。

Django とは

Django とは、 Python 用の Web フレームワークの中で最も人気のあるフレームワークの 1 つです。 Flask と違い、Django は Web アプリケーションの実装に必要となると予測される多くの機能の提供してくれるフルスタックフレームワークです。

環境のセットアップ

Setup your Environment - Guide to using Django with Zappa に従い、環境のセットアップを行います。 本ブログでは pyenvpyenv-virtualenv を使って仮想環境を用意します。 ※ Zappa が Python の 3.7 系ではまだ利用できないため今回は 3.6 系で環境を作成します。

$ pyenv virtualenv 3.6.6 djangoenv

続いて、ディレクトリを作成し Django と Zappa をインストールします。

$ mkdir zappatest && cd zappatest
$ pyenv local djangoenv
$ pip install django zappa

※もしインストール中に UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 2339: ordinal not in range(128) のエラーが発生した場合は、以下を実行後再度インストールを行ってください。

$ export LANG=en_US.UTF-8 LANGUAGE=en_US.en LC_ALL=en_US.UTF-8

Django のセットアップ

Core Django Setup - Guide to using Django with Zappa に従い、 Django のセットアップを行います。

IAM 権限の設定

Minimum AWS policies for example. を参考に必要な権限を持った IAM Role をデプロイ用インスタンスにアタッチします。

Django プロジェクトの作成

デモ用 Django プロジェクト frankie を作成します。

$ django-admin startproject frankie .

実際に動かしてテストしてみましょう。 以下を実行して、ブラウザから http://[EC2 の IP アドレス]:8000 にアクセスしてください。

$ python manage.py runserver 0.0.0.0:8000

以下のような画面がでるはずです。 Django が持つセキュリティ機能によってアクセスが弾かれているので frankie/settings.pyALLOWED_HOSTS に EC2 の IP アドレスを追加して上げる必要があります。 詳しい内容は Security in Django | Django documentation | Django を見てみてください。

$ vim frankie/settings.py
...
ALLOWED_HOSTS = [ "xx.xx.xx.xx" ]
...

修正後にもう一度 runserver を実行しブラウザにアクセスすると以下画面が表示されるはずです。

Zappa のセットアップ

デフォルトのリージョンを指定していない場合は、先に以下を実行しデフォルトリージョンの設定を行ってください。

$ aws configure --profile zappa
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]:
$ cat ~/.aws/config
[profile zappa]
region = ap-northeast-1

続いて以下に従い、 Zappa のセットアップを行います。

$ zappa init

███████╗ █████╗ ██████╗ ██████╗  █████╗
╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗
  ███╔╝ ███████║██████╔╝██████╔╝███████║
 ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║
███████╗██║  ██║██║     ██║     ██║  ██║
╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝  ╚═╝

Welcome to Zappa!

Zappa is a system for running server-less Python web applications on AWS Lambda and AWS API Gateway.
This `init` command will help you create and configure your new Zappa deployment.
Let's get started!

Your Zappa configuration can support multiple production stages, like 'dev', 'staging', and 'production'.
What do you want to call this environment (default 'dev'): # デフォルトでよいのでなにも入力せずエンター

AWS Lambda and API Gateway are only available in certain regions. Let's check to make sure you have a profile set up in one that will work.
Okay, using profile zappa!

Your Zappa deployments will need to be uploaded to a private S3 bucket.
If you don't have a bucket yet, we'll create one for you too.
What do you want to call your bucket? (default 'zappa-7o1fjyn6x'): zappa-bucket # デプロイ用の S3 バケットがある場合はバケット名を指定

It looks like this is a Django application!
What is the module path to your projects's Django settings?
We discovered: frankie.settings
Where are your project's settings? (default 'frankie.settings'): # Zappa が自動的に Django の設定ファイルを見つけてくれるのでそのままエンター

You can optionally deploy to all available regions in order to provide fast global service.
If you are using Zappa for the first time, you probably don't want to do this!
Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]: # グローバルにデプロイはしないのでそのままエンター


Okay, here's your zappa_settings.json:

{
    "dev": {
        "aws_region": "ap-northeast-1",
        "django_settings": "frankie.settings",
        "profile_name": "zappa",
        "project_name": "zappatest",
        "runtime": "python3.6",
        "s3_bucket": "sample-bucket"
    }
}

Does this look okay? (default 'y') [y/n]: # 確認して問題なければそのままエンター


Done! Now you can deploy your Zappa application by executing:

        $ zappa deploy dev

After that, you can update your application code with:

        $ zappa update dev

To learn more, check out our project page on GitHub here: https://github.com/Miserlou/Zappa
and stop by our Slack channel here: https://slack.zappa.io

Enjoy!,
 ~ Team Zappa!

デプロイ

Zappa でデプロイしてみましょう。 自動的に Lambda 上で稼働する Django プロジェクトへ HTTP リクエストを送るための API Gateway を作成してくれます。

$ zappa deploy dev
Calling deploy for stage dev..
Creating zappatest-dev-ZappaLambdaExecutionRole IAM Role..
Creating zappa-permissions policy on zappatest-dev-ZappaLambdaExecutionRole IAM Role.
Downloading and installing dependencies..
 - sqlite==python36: Using precompiled lambda package
Packaging project as zip.
Uploading zappatest-dev-1547095386.zip (14.4MiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 15.1M/15.1M [00:00<00:00, 29.7MB/s]
Scheduling..
Scheduled zappatest-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading zappatest-dev-template-1547095398.json (1.6KiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.63K/1.63K [00:00<00:00, 47.6KB/s]
Waiting for stack zappatest-dev to create (this can take a bit)..
 75%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████                                           | 3/4 [00:09<00:04,  4.81s/res]
Deploying API Gateway..
Deployment complete!: https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev

作成されたエンドポイント https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev へブラウザからアクセスしてみると、 前回同様アクセスできないので、 xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com を追加し再デプロイします。

$ vim frankie/settings.py
…
ALLOWED_HOSTS = [ 'xx.xx.xx.xx', 'xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com' ]
…

修正後に内容を反映させるため update コマンドを実行します。

$ zappa update dev
Calling update for stage dev..
Downloading and installing dependencies..
 - sqlite==python36: Using precompiled lambda package
Packaging project as zip.
Uploading zappatest-dev-1547096673.zip (14.4MiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 15.1M/15.1M [00:00<00:00, 8.51MB/s]
Updating Lambda function code..
Updating Lambda function configuration..
Uploading zappatest-dev-template-1547096683.json (1.6KiB)..
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.63K/1.63K [00:00<00:00, 47.1KB/s]
Deploying API Gateway..
Scheduling..
Unscheduled zappatest-dev-zappa-keep-warm-handler.keep_warm_callback.
Scheduled zappatest-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Your updated Zappa deployment is live!: https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev

もう一度 https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev へアクセスすると以下画面が表示されるはずです。 この 404 レスポンスは Django アプリケーションが正しく動いていることを示しています。

静的ファイルのホスティング

Hosting Static Files - Guide to using Django with Zappa に従い、 Django で提供されている静的ファイルを S3 に配置しホスティングを行っていきます。

S3 のセットアップ

バケットの作成

今回は S3 に静的ファイルを配置しホスティングを行うため、ホスティング用のバケットを作成してください。 本ブログ上ではバケット名を zappa-static とします。

CORS の設定

Lambda から S3 のオブジェクトへクロスオリジンアクセスを可能にするために CORS の設定を行います。 バケットの設定から Permissions タブを選び、 CORS configuration ボタンをクリックし以下を入力します。 ※今回はサンプルとしてシンプルな設定にしていますが、実際の本番環境等で利用する際はスコープを狭めるなど考慮が必要です。

*GET3000Authorization

パブリックアクセス設定の変更

バケットの設定から Permissions タブを選び、 Manage public access control lists の項目を以下のように False に変更します。

Django プロジェクトの設定

まず、静的ファイルを S3 とやり取りするために django-s3-storage をインストールします。

$ pip install django-s3-storage
$ pip freeze | grep django-s3-storage
django-s3-storage==0.12.4

次に、 settings.pyDjango-S3-Storage を追加します。

$ vim frankie/settings.py
…
INSTALLED_APPS = [
     …
     'django_s3_storage',
]
…

更に末尾に Django-S3-Storage の設定を追加します。

# STATIC_URL = '/static/'
YOUR_S3_BUCKET = "zappa-static" # ホスティング用バケットのバケット名を入力

STATICFILES_STORAGE = "django_s3_storage.storage.StaticS3Storage"
AWS_S3_BUCKET_NAME_STATIC = YOUR_S3_BUCKET

# These next two lines will serve the static files directly
# from the s3 bucket
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % YOUR_S3_BUCKET
STATIC_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN

# OR...if you create a fancy custom domain for your static files use:
#AWS_S3_PUBLIC_URL_STATIC = "https://static.zappaguide.com/"

静的ファイルを S3 へ配置します。

$ zappa update dev
$ zappa manage dev "collectstatic --noinput"

アクセスしてみる

早速アクセスしてみましょう! ブラウザを開き、 https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/admin にアクセスしてみてください、以下が表示され S3 に配置した CSS ファイルが読み込まれています!

おわりに

今回はドキュメントに沿って、 Django を Zappa でデプロイする手順をまとめてみました。(まだまだやることはありますが… 手順は多いですが、これならサクサク作れそうですね!