この記事は Heroku Advent Calendar 2015 22 日の記事です。
はじめに
Heroku と言えば Ruby!な印象がどうしても強いですが、Ruby 以外にも様々な言語をサポートしています。
Python もそのひとつです。
ref. Language Support | Heroku Dev Center
Python(Django) に関しては公式のチュートリアルもあるので、とりあえず Heroku にアプリケーションを立ち上げるところまではそこまで苦労せずできます。
- Getting Started on Heroku with Python | Heroku Dev Center
- Getting Started on Heroku with Python | Heroku Dev Center
※その時のメモはこちら
- Herokuのpythonチュートリアル(Getting Started with Python on Heroku)をやってみた - dackdive's blog
- Heroku+DjangoでPostgresをローカルで使う時につまづいた点 - dackdive's blog
が、初期設定(特に Postgres)まわりが詳しく書かれておらずつまづくポイントになりそうだというのと、
チュートリアルによって微妙に使っているライブラリやファイルの内容が異なっていたりして
「じゃあ自分で Django アプリケーションを作るにはどこからスタートしたらいいんだろう?」
というのがイマイチわかりませんでした。
なので、今回はそのあたりを簡単にまとめてみます。
先に結論から言ってしまうと、公式ドキュメントの Django and Static Assets | Heroku Dev Center で紹介されているこちらのリポジトリからスタートするのがいいんじゃないかなと思っています。
上記のテンプレートの使い方はおおむね README に書いてある通りなので、既に Python や Heroku に詳しい方は README を読むだけで理解できると思います。
ここでは最初の環境構築と、上記テンプレートの簡単な解説を加えて書きます。
環境構築
前提として、Heroku のアカウント作成や Heroku Toolbelt のインストールは済んでいるとします。
また、使用した私の PC はMac OS X 10.10.5 Yosemite です。
virtualenv, Django のインストール
チュートリアルにも書いてますが、Heroku で Python を扱うには virtualenv を入れると良いです。
Python 自体は pyenv などを入れて自分が使いたいバージョンをインストールするといいと思います。
※ pyenv, virtualenv あたりに詳しくない方はこちらの記事をどうぞ。
[Python]pyenvとvirtualenvとpyenv-virtualenv - dackdive's blog
また、先ほどのリポジトリからテンプレートを clone してくるときに Django のコマンド (django-admin
) が必要になるため一緒にインストールします。
# pyenv-virtualenv を使っている場合 $ pyenv install 2.7.10 # 開発に使うバージョン。任意 $ pyenv virtualenv 2.7.10 heroku-py27 # 任意の仮想環境名 $ pyenv global heroku-py27 $ pip install virtualenv $ pip install django
ここで入れる Django は実際にアプリケーションを稼働させる時には使いません。
が、特に理由がなければバージョンは揃えておいた方がいいんじゃないでしょうか。
Postgres のインストール
Heroku の設計思想でもある The Twelve Factor App の X. Dev/prod parity によれば、開発環境と本番環境はできるだけ一致させるのが望ましいとされています。
Heroku でサポートしている DB はいくつかありますが最もポピュラーなのはおそらく Postgres なので、
別の DB を使う場合を除いてはローカルで動かす時も Postgres を使うようにした方が良いです。
チュートリアルでは Postgres.app をインストールするよう勧められているので今回もそうします。
が、Homebrew でもインストールは可能なようです。
Postgres.app からインストールした場合は CLI を使えるようにパスを通す必要があります。
公式ドキュメント を参考に、.bashrc
や .zshrc
に以下のように書きます。
export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/9.4/bin
※記事執筆時点での Postgres.app のバージョンは 9.4.5 です。実際に設定するときは一度公式ドキュメントから PATH を確認することをオススメします。
(2016/02/12追記)
いつの間にか Postgres.app 9.5 系がリリースされ、PATH
の設定も以下のように変更になってました。
export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/latest/bin
これで 9.5 以降はバージョン上がっても PATH
を変更する必要がなさそうですね。
ただ、手元の 9.4 系では latest
というシンボリックリンクはないようです。
(追記ここまで)
また、ローカルで Heroku アプリを開発するために DATABASE_URL
という環境変数も必要になるのでこれも記述します。
ref. https://devcenter.heroku.com/articles/heroku-postgresql#local-setup
export DATABASE_URL=postgres:///$(whoami)
テンプレートの clone
↑で紹介したリポジトリからテンプレートを clone してきます。
このとき、通常の git clone
ではなく Django の django-admin
コマンドを利用して以下のようにします。
$ django-admin.py startproject --template=https://github.com/heroku/heroku-django-template/archive/master.zip --name=Procfile [プロジェクト名]
このコマンドの説明は最後におまけとして載せています。
また、URL 部分が長くて覚えられないので、私は ~/.zshrc
に関数として登録しています。
function django-heroku() { django-admin.py startproject --template=https://github.com/heroku/heroku-django-template/archive/master.zip --name=Procfile $1 }
データベースの設定がうまくいっているか確認する
clone したリポジトリに移動し、以下のコマンドを実行してエラーにならなければ OK です。
$ python manage.py migrate ...(略) Operations to perform: Apply all migrations: admin, contenttypes, auth, sessions Running migrations: No migrations to apply.
仮想環境を作成する
virtualenv を使って仮想環境を構築し、必要なパッケージをインストールします。
# `venv` というディレクトリは .gitignore に記載されています $ virtualenv venv # 仮想環境をアクティベート $ source venv/bin/activate (venv) $ # パッケージのインストール。必要なものはすべて requirements.txt に記載済み (venv) $ pip install -r requirements.txt
ローカルで起動する
$ heroku local web
でローカルサーバーを立ち上げます。
http://localhost:5000/ にアクセスして画面が表示されれば OK です。
もしうまく起動しない場合はこちらの記事も参考にしてみてください。
[Heroku][Django]Postgres.appで `'django_postgrespool' isn't an available database backend.` エラー - dackdive's blog
基本、heroku local web
でうまく起動しなかった時は python manage.py runserver
で起動した方が詳細なエラーが得られます。
Heroku にデプロイ
ここはチュートリアルを読めばわかる話でもあるのでさらっと流します。
README にも書いてるようにコミットして heroku
に push、で基本的には OK です。
$ git init
$ git add -A
$ git commit -m "Initial commit"
$ heroku create
$ git push heroku master
$ heroku run python manage.py migrate
おわりに
というわけで、「Python/Django は知ってるけど Heroku は初めて」という方に向けて
最初にハマってしまいそうな(というか自分自身がよくわからずハマってしまった)環境構築部分の説明と、便利なテンプレートを紹介しました。
この後は普通の Django アプリケーション開発と同じように進めていけばいいはずです。
おまけ
ここから下は自分で調べたことのメモ書きとして。
テンプレートの clone について
リポジトリからテンプレートを clone するときの以下のコマンドについてです。
$ django-admin.py startproject --template=https://github.com/heroku/heroku-django-template/archive/master.zip --name=Procfile [プロジェクト名]
django-admin.py startproject
に2つのオプション template
と name
を指定しています。
startproject
または startapp
コマンドには --template=PATH
を指定することが可能で、指定した PATH のディレクトリからファイルをコピーして新規プロジェクトを作成できます。
PATH には .zip
など圧縮したファイルも指定可能です。また、圧縮ファイルであればローカルのディレクトリだけでなく http, https, ftp などの URL で指定することも可能です。
(ref. https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-option---template)
また、startproject
する際にファイル内のテンプレート変数({{ variable }}
)を置換することができます。
(ref. https://docs.djangoproject.com/en/1.8/ref/django-admin/#startproject-projectname-destination )
上記ドキュメントから引用すると
When Django copies the project template files, it also renders certain files through the template engine: the files whose extensions match the
--extension
option (py by default) and the files whose names are passed with the--name
option. The template context used is:
- Any option passed to the
startproject
command (among the command’s supported options)project_name
– the project name as passed to the commandproject_directory
– the full path of the newly created projectsecret_key
– a random key for theSECRET_KEY
settingdocs_version
– the version of the documentation:'dev'
or'1.x'
一番上の Any option passed ...
はよくわかりませんが、
--extension
オプションで指定した拡張子のファイル(デフォルトはpy
)--name
オプションで指定したファイル
内に存在する project_name
, project_directory
などの変数が自動的に置換されるようです。
Django で静的リソースを扱う
デフォルトでは Django は画像やCSSなどの静的リソースを扱うことができません。
正確には、django.contrib.staticfiles
というミドルウェアを INSTALLED_APPS
に指定することで開発中は静的リソースを扱えるようになりますが
DEBUG=True
のときのみ、という制約があるため本番環境では別の手段を取る必要があります。
ref. Managing static files (e.g. images, JavaScript, CSS) | Django documentation | Django
今回のテンプレートでは Whitenoise というライブラリを利用しています。
settings.py および wsgi.py を見ると以下のようになっています。
settings.py
# Simplified static file serving. # https://warehouse.python.org/project/whitenoise/ STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
wsgi.py
from django.core.wsgi import get_wsgi_application from whitenoise.django import DjangoWhiteNoise application = get_wsgi_application() application = DjangoWhiteNoise(application)
なお、Getting Started with Django on Heroku だと dj-static というライブラリを使っています。
(wsgi.py で DjangoWhiteNoise
のかわりに Cling
とかってやってるやつ)
これについては正直違いがわかりませんが、dj-static は Python3 に対応していないといったブログ記事 が見つかったりしたので
特に問題にならない限りは WhiteNoise を使っていこうと思います。
余談ですが、Django のミドルウェアである django.contrib.staticfiles は collectstatic
コマンドを使うために必要だそうです。
さらにおまけ:Django で py.test を使えるようにするにはこちらのパッケージを入れるとよさそう。
http://pytest-django.readthedocs.org/en/latest/tutorial.html