Django で作成したアプリの公開

記事
IT・テクノロジー
Django で作成したアプリの公開
インターネット上で Django で作成したアプリを公開すると、開発環境とは大きく状況が変わってきます。 開発環境では、たくさんのアクセスが同時に発生する事は殆どないので、開発用のサーバーはシンプルに作られています。 しかし、インターネットに公開する場合にはこうした開発用の環境では十分ではありません。そこで、公開時には別の設定が必要になります。そこで、この連載では、仮想マシーンのサーバーに Django のアプリを実装する方法を紹介しています。


Django のアプリに必要なものは?

Django のアプリを Web ホスティングするのに必要なサーバーの機能は2つあります。

* HTTP のリクエストを処理する機能
* アプリケーションを起動する機能
Django のアプリケーションをインターネットに公開する際によく利用されるのが、

* NGINX (Web サーバー)
* GUNICORN  (アプリケーションサーバー)
前回の記事では、NGINX を仮想マシーンのサーバーにインストールして基本的なページが表示できるのを確認しました。 この記事では、GUNIXRON を起動して Django のアプリを表示できるようにします。

開発環境との基本的な違い

開発環境では、「manage.py」を起点にサーバーを起動しています。公開する場合は、Django の場合、WSGI という仕組みを使ってアプリケーションサーバーを起動します。 Django でプロジェクトを作成すると、この WSGI のアプリケーションのサーバーを起動するためのスクリプト「wsgi.py」が予め作られています。 これを利用して、公開用に必要な設定などを読み込むようにします。

Django のプロジェクトの基本設定は、プロジェクトフォルダの「settings.py」に書かれています。その設定は、開発時は「manage.py」、公開時は「wsgi.py」を実行して取り込む仕組みになっています。

公開時には、いろいろな設定を公開用に書き直す必要が出てきます。例としては

* 秘密鍵(secret key)
* データベース(開発用の SQLite から置き換える)
* IP アドレス(ALLOWED_HOSTS)などの設定
* 静的ファイルの置き場所(static/media のパス)
* デバッグ用の設定(公開時は無効にするのが普通です)

こうした設定は、開発時と公開時で違うため、設定をどのように管理するかも重要なポイントになります。一つの方法は、ファイルを分ける方法があります。公開用の「settings.py」と開発用を別のファイルにして名前を変えて対応する方法があります。 また、同じファイルでコメントアウトする場所を変えて対応することも可能です。

開発が終わって、公開するときに入れ替えてそれで終わる場合は大きな問題ではありません。しかし、公開環境で問題が出たり、昨日の追加などを後から行う場合など、開発と公開の環境を頻繁に入れ替える事はよくあります。 こうした対応時に、ミスが起こりやすくなるという問題があります。

同じファイルで設定を管理する

そこで、よく利用される方法が、外部のモジュールを導入して、開発用と公開用の設定を同じファイルで管理する仕組みを導入する方法です。 この記事で紹介するのは、以前の投稿で紹介した「django-configurations」というパッケージを利用する方法です。この方法ならば、Python のクラスで「開発用(Development)」と開発用のクラスを継承した「公開用(Production)」のクラスを別々に設定して、書き換える設定のみを公開用のクラスでオーバーライドする方法です。

from pathlib import Path
import os
from configurations import Configuration, values
class Development(Configuration):
    """
    開発用の設定を記述(基本的にデフォルトの設定をこの中にコピー)
    """

class Production(Development):
    """
    公開用の設定(公開用で書き換える記述のみを指定)
    """
    DEBUG = False
    SECRET_KEY = values.SecretValue()
このように設定を開発用と公開用で分けた上で、「manage.py」や「wsgi.py」でどちらを使うかを指定します。

開発用の設定
開発用の設定では、「manage.py」で開発用の設定を指定します。基本設定は、「settings.py」で読み込んで、開発用の設定を読み込む様に変更します。クラスによる使い分けは、「django-configurations」で行っているので、そのモジュールを取り込むようにしておきます。

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'utility.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Development')
    try:
        from configurations.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)
if __name__ == '__main__':
    main()
公開用の設定
公開用の設定は、別のファイル「wsgi.py」で行うので公開用の設定はこのファイルで指定します。こちらは公開専用なので、公開用の設定を読み込む様にします。

import os
from configurations.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'utility.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Production')
application = get_wsgi_application()
公開用のサーバーに開発した Django のプロジェクト情報をコピーします。コピーの方法はいろいろありますが、便利なのは、GitHub を利用する方法です。もう一つは、FTP や SFTP でファイルを開発用の PC から公開用のサーバーにコピーする方法です。

今回は GigHub を利用する方法で Django のプロジェクト情報をコピー(クローン)する方法を紹介します。この方法だと、開発したデータを GitHub にプッシュして置いて、公開用のサーバーにクローンを作成してコピーする事が簡単にできます。また、ファイルを修正した場合の更新も簡単にできるので、先日紹介した、Django のアプリを公開できるホスティングサービスでも採用されている方法です。

GitHub でレポジトリを作成した後に、Django のプロジェクトのトップフォルダで以下のコマンドを実行します。

$ git init
$ git remote add origin h t t p s://github.com/xxxx/utility
$ git add *
$ git commit -m "initial commit"
$ git push origin master
(*)GigHub にレポジトリを既に作ってある前提です。 これで、GitHub に開発データの情報がアップロードされます。

あとは、サーバーに SSH でログインして、GigHub からアップロード(プッシュ)した Django のデータを取得(クローン)します。

$ git clone  h t t p s://github.com/xxx/utility
これで、Django のデータが公開用のサーバーにコピーされます。

公開用のサーバーの設定

公開用のサーバーの設定では、幾つかやる事があります。

* 公開用の Django のプロジェクトを置く場所
* 公開時に使用する秘密鍵(secret key)
* Django に必要なパッケージのインストール
* 細かい設定値の変更
* データベースの置き換え
* セキュリティ対策(サーバー上のデータの所有者とアクセス権など)
などいろいろやる事があります。実際は、サーバーで動作する OS の知識なども必要になってきます。

今回の目的は、仮想 Web サーバーにどの様にして Web アプリを稼働させるかが目的なので、まずは「機能」を稼働させる事を中心に説明します。細かい設定の話は別途記事を描く予定なので今回は、仮想マシーンなのでセキュリティ面は余り考慮しないことにします。

プロジェクトを置く場所はとりあえず、サーバー上に作成したアカウントのホームフォルダに置く事にします。サーバーに SSH でログインして、そのフォルダで GitHub からデータをコピーしてください。(コマンドは上で説明した通りです。)

必要なパッケージのインストール
手動で必要なパッケージをインストールしても構いませんが、自動化したい場合は、Django のプロジェクトのトップレベルのフォルダに「requirements.txt」を作成して、Git レポジトリに入れておくと便利です。

$ pip3 freeze > requirements.txt

でインストールされている、パッケージの一覧が保存されるので、開発用の PC 上で実行してファイルを GigHub にプッシュする前に作成しておきます。

サーバー側では以下のコマンドを実行すると、必要なパッケージをまとめてインストールできます。仮想環境を作成した上で

$ python3 -m virutalenv venv
$ source venv/bin/activate
(venv) $ cd [Djangoのプロジェクトフォルダ]
(venv) $ pip3 install -r requirements.txt
これで必要なパッケージがインストールされます。

これに加えて、公開用のサーバーでは、「gunicorn」が必要なので、これもインストールしておきます。

(venv) $ pip3 install gunicorn
もしくは、requirements.txt にこのパッケージを追加しておいても OK です。

環境変数の設定
公開に必要な設定の変更は django-configurations を使うと環境変数で指定して読み込む事ができます。Django のプロジェクトフォルダに「production.conf」というファイルを指定して、必要な設定をしておくと便利です。

DJANGO_SETTINGS="utility.settings"
DJANGO_CONFIGURATION="Production"
DJANGO_SECRET_KEY="2pr9IO6nRC!*^ty3yy19Lr1dv7XDto6r(UPPcvJ5paY6T\A%\^"
DJANGO_DATABASE_URL="postgres://srd7admin:appadmin@localhost/appdb"
DJANGO_STATIC_ROOT="/var/www/app/static"
DJANGO_MEDIA_ROOT="/var/www/app/mendia"
DJANGO_ALLOWED_HOSTS="10.16.40.22"
環境変数の指定には、以下のコマンドで指定できます。

$ export $(cat production.conf | xargs)
で環境変数としてアクセスできる様になります。

Gunicorn の起動

$ gunicorn -b 10.16.40.22:8000 utility.wsgi:application
で Gunicorn のサービスが起動できるので 「10.16.40.22:8000」にアクセスすると、Django のページにアクセスできるようになります。

まとめ

まずは、簡単に Django のアプリをサーバーで動かす方法を紹介しました。

この方法では、自動的に「Gunicorn」のアプリケーションサーバーが起動されないので、実際のサービスではサービスの起動に課題が残ります。 また、環境変数の中に秘密鍵(secret key)があるので、Git にファイルをプッシュするときには注意が必要です。通常は「.gitignore」に入れて GitHub などのレポジトリには入れない方が無難で個別にファイルをコピーするようにした方が安全です。

秘密鍵は、Python のスクリプトで生成できます。生成したら管理をきちんとすることが大切です。

まずは、機能の実現が第一なので開発環境で動作する物が、公開用のサーバーでも動作することが第一ステップです。あとは、データベースの置き換えを含めてもう少し細かい事を解説していく予定です。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す