タイトルの通り、HerokuというとどうもRubyというかRailsなイメージがある。
だけど、RubyだけじゃなくてPythonも使えちゃうんだよ!ということで、PythonのフレームワークであるDjangoを動かす方法を投稿してみようかなと思います。
Djangoって?
Python製のいわゆるフルスタックWebフレームワークで、このフレームワークにWebアプリを作るために必要なものがすべて詰まってます。
例えばJavaだと
- AppサーバーとしてのTomcat
- MVCフレームワークとしてSpring MVC
- DBアクセスとしてのHibernte
- などなど
と色々組み合わせて作っていく必要がありますが(最近ならJava EEだけで頑張ることもできるかも?)、Djangoは基本的にDjangoだけで開発が可能です。
コーディングはもちろんPythonで行うので、Pythonが使える、もしくはこれからPythonを勉強してみたい という人には、お勧めです。
なお、明日はPython製の別のフレームワーク、Flaskに関する記事をkounoikeさんが書いてくれる様なので、そちらも参考にしてみるといいかもしれません。
DjangoをHerokuにデプロイする際に考慮する点
僕が主にハマったポイントです。ここでは、Herokuを本番環境、実運用する環境とする前提で話をします。
Pythonのバージョン
heroku上のデフォルトのPythonのバージョンは2.x系です。3.x系を利用したい!という場合は、herokuにその旨伝えてあげる必要があります。
デバッグモード
Djangoは、デバッグモードというものを備えていて、環境を作った際はデフォルトでその機能がOnになっています。
これがOnになっている事で、例えばエラーになった際に詳細な内容を表示してくれます。以下は404エラー例。現在URLとして認識しているURLが表示されていますが、これが運用させるページで表示されてしまうのは困りものです。
データベース
Djangoでは、設定を変更しない限り、開発中はSQLiteをDBとして利用しています。ただし、Heroku上で利用できるのは基本的にPostgresです。なので、DBの設定も変更してあげる必要があります。
Appサーバー
フルスタックフレームワークという事で、Django自身もAppサーバーとしての機能を持っています。
しかし、あくまでも開発用という位置付けで、実運用する際はAppサーバーとしてカリカリにチューニングされた、専用のものを用いる事が推奨されます。
staticファイルの取り扱い
Appサーバーでは、基本的にアプリケーションを動かす為のサーバーなので、staticファイルの取り扱いが得意ではありません。他の言語のAppサーバーでも、staticファイルを取り扱う為にApacheを置いたりnginxを置いたりするかと思います。
この点についても、考慮が必要です。
解決策
僕はこうやって動かしてる!という解決策なので、もし「こうやったほうがいい!」などありましたら突っ込みよろしくお願いします。
Pythonのバージョン
これは簡単です。プロジェクトのカレントフォルダにruntime.txtというファイルを用意し、そこで以下のようにPythonのバージョンを指定してあげるだけです。
python-3.4.1
注意点としては、利用できるバージョンは決まっているので、以下のページを参考にして利用するバージョンを選んでください。
Specifying a Python Runtime
デバッグモード
デバッグモードの設定は、settings.py
で指定します。しかし、herokuにpushする際に変更して、ローカルで開発する際は戻して・・・とやると大変です。
ので、僕の場合は以下のように、ホスト名(マシン名)にlocalが入っている場合のみデバッグモードになる様にしています。
こちらは僕の開発環境が"hogehoge.local"といった名前を付けている為であり、ご使用のホスト名に合わせてlocalの部分は変更してください(逆に、heroku側のマシン名で指定するのもありか)
if 'local' in hostname:
DEBUG = True
TEMPLATE_DEBUG = True
else:
DEBUG = False
TEMPLATE_DEBUG = False
ALLOWED_HOSTS = ['*']
データベース
こちらも、settings.py
で指定することになりますが、環境に合わせて書き換えるといったことはしたくない。
そこで、以下のような記載を行うことにします。
if 'local' in hostname:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
else:
import dj_database_url
DATABASES = {
'default': dj_database_url.config()
}
ここで一つポイントとなるのが、
import dj_database_url
DATABASES = {
'default': dj_database_url.config()
}
の部分。dj_database_urlなるAPI(pipでインストール可能)を用いることで、コード内に接続先やユーザー名、パスワードなど記載する必要がないんです。
これは衝撃でした。
Appサーバー
PythonのWebアプリケーションフレームワークは、WSGIという規格があって、こちらに準拠したサーバーであればどれを利用しても構いません。
herokuのドキュメントでは、gunicornを用いた説明があるので、そちらに乗っかることにします。
Deploying Python Applications with Gunicorn
こちらを利用するには、pipでgunicornをインストールし、settings.pyのINSTALLED_APPSの末尾にgunicornの記載を追加します。
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'プロジェクト名',
'gunicorn', ## ←この行追加
)
そして、開発時は
$ python manage.py runserver 0.0.0.0:8080
といった形で起動していたものを、後述の方法(Procfileの記載)によってmanage.py
ではなくgunicornで起動することになります。
staticファイルの取り扱い
これがなかなか情報を見つけられなくて苦労しました。
結論で言うと、Whitenoiseというものを利用します。
pipでwhitenoiseをインストールした後、settings.py
を上のリンクの説明に従って変更します。
そして、settings.py
がある場所と同じフォルダにwisgi.pyというファイルを用意し、そこにリンクにも記載のある以下の内容を記述します。
from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise
application = get_wsgi_application()
application = DjangoWhiteNoise(application)
そして、gunicornも含め、設定したものを利用して起動されれる様に、Procfileに以下の様に記載します。
web: gunicorn --env DJANGO_SETTINGS_MODULE=プロジェクト名.settings プロジェクト名.wsgi --log-file -
こちらの設定で、herokuのリポジトリにpushすれば、起動するはずです!
パフォーマンスとかどうなの??
上記設定でデプロイしたアプリケーションを先日リリースし、リリース初日には2万PVほどありましたが、無料枠の範囲で問題なく元気に動いてました。いや、herokuほんとすごい。
以下にアプリケーションを実際に作った際の経緯を書いたブログのリンクを置いておきますので、こちらも参考にしていただけたらなと思ってます
>>実際に動かしてるサービス
Love Points
追記
heroku & Djangoで作った、実際に運用しているサービス(↑のとは別物)のソースコードをgithubにアップしました。
構成等、参考になれば幸いです(汚いソースですが・・・)
お次は・・・
明日、12/8のHeroku Advent Calendar 2014はkounoikeさんのFlaskに関するお話です!Pythonネタが続くということで、ワクワクしております。
そして、記事に触発されて、Pythonでアプリケーション作る人がもっともっと増えたらななんて思ってます。
kounoikeさん、明日の記事楽しみにしてます!!