Cloud9で開発したdjangoプロジェクトをherokuで公開
プロローグ
前回の記事でherokuを少し使ってみました。
あれから3ヶ月,Rの経験値も上がってきましたが,今回はRではなくPythonを使ったお話です。
Rはパッケージも多く,昨年は書籍もたくさん出ましたし,最近はTokyoRを通じて知りあったRガチ勢の皆様が四六時中参加しているslackもあって,とても便利なのですが,基本的に統計処理を念頭に作られたものということもあり,データの前処理ではawkを使ったりしていました。しかしawkは会社のWindows7(32bit)環境で使うにはいろいろ面倒です。
そこで実は2015年夏くらいから情報収集を始め,Python関連の勉強会にもいろいろ参加してました(あとjuliaも)。
- みんなのPython勉強会StartPythonClub(#StaPy)
- Pythonもくもく会@アライドアーキテクツ(#mokupy)
- Python入門者の集い(#PyNyumon)
- TokyoDjangoMeetup(#djangoja)
- Pythonエンジニア養成読本読書会(#pymook)
- Python mini Hack-a-thon(#pyhack)
並べてみるといっぱい参加したみたいですが,複数回参加したのは一番上のStartPythonClubだけで,他のはまだ1回ずつしか参加してません。
そんなPython初心者の私が職場の同僚から「djangoでwebアプリを作りたい」という相談を受けて,
- Python3で
- django1.9で
- Cloud9IDE上でWebアプリを作って
- SQLite3からPostgreSQLに移行して
- herokuにデプロイ
までをがんばった,というお話です。
特に3〜5で苦労したので,そのあたりについて重点的にまとめてみたいと思います。
準備するもの
これだけです。
ちなみになんでわざわざCloud9かというと,Pythonに興味を持ち始めた同僚の質問にいろいろ答えるにあたり,同一の環境を用意することができるクラウド上の統合開発環境が一番便利だったからです。
あと,自宅ではMac,会社ではWindows7のため,OSや文字コード,改行コードの違いに振り回されたくない,というのもあります。
Cloud9でPython3&djangoのアプリ開発
djangoワークスペースを作る
Cloud9にログインし,ダッシュボード画面からCreate a new workspaceをクリックします。
プロジェクト名(仮にabc)を入力し,下の方のテンプレート一覧からdjangoテンプレートを選択してCreate workspaceボタンをクリックします。
djangoテンプレートでワークスペースが作成されました。初期のフォルダ構成はこうなっています。
c9_abc
というのがdjangoのプロジェクトフォルダーです。
Python3の環境にする
Cloud9のテンプレートではPython2.7とそれに対応したdjangoが構成されます。
私はPython3で開発したいので,Python3で動くように設定を変えましょう。
ワークスペースのメニューからCloud9 - Preferenesでプロジェクト設定画面を開きます。
Language SupportセクションでPython2をPython3に変更します。
ただし,PreferenceをPython3にしても,コマンドラインで python --version
とするとPython2.7のままです。
$ python --version
Python 2.7.6
あとで何度もpython manage.py migrate
などと叩く予定なので /usr/bin/python
がPython3を指すようにしておきましょう。
$ sudo mv /usr/bin/python /usr/bin/python2
$ sudo ln -s /usr/bin/python3 /usr/bin/python
$ python —version
python 3.4.3
方法はこちらの記事を参考にしました。1
こういうことを気兼ねなくできるのもCloud9の便利なところですね。
さて,abcプロジェクトを走らせてみましょう。メニューバーのRun Projectをクリックします。
「djangoがないよ」と言っているようです。Python3にしたせいでdjangoが入っていないのかも。
ということで,djangoをインストールします。Python3なのでpip3を使いましょう。
$ sudo pip3 install django
改めてRun Projectをクリックすると,今度はちゃんと動きました。
heroku用のdjango系ファイル一式と置き換える
Cloud9上で開発するだけならこのままでも良いのですが,あとでherokuにデプロイするために,herokuが用意しているdjangoプロジェクトのテンプレートと置き換えておきます。
この辺の手順はこちらの記事 2 を参考にしました。
まずワークスペースを作成した時に自動的に構成されたdjangoプロジェクトを削除します。
プロジェクトフォルダーだけでなく,manage.pyなども消してしまいます。
次にGitHubからheroku用のdjangoテンプレートを持ってきます。
$ django-admin.py startproject --template=https://github.com/heroku/heroku-django-template/archive/master.zip --name=Procfile c9_abc
一番最後のc9_abcはさっき消したdjangoプロジェクトフォルダと同じ名前です。
フォルダ構成をみると,ちょっと変ですね。階層がひとつずれています。
manage.pyが最上層にくるように,1階層ずつ上の階層に移動します。最下層に残ったabc\c9_abc\c9_abcフォルダは空っぽになりますので削除します。
参考にした記事 ではCloud9上で動くようにsettings.pyやwsgi.pyを編集していますが,herokuにデプロイするときにまた戻す必要があり面倒くさいので,必要なライブラリをインストールしてしまいます。
$ sudo pip3 install dj-database-url
$ sudo pip3 install Whitenoise
$ sudo pip3 install Gunicorn
Run Projectで動作確認します。
アプリ開発&テスト
今回はアプリの中身は割愛します。
なにせPython初心者なので,django以前にPythonの文法やライブラリの使い方をいちいち調べないと進みません。
Pythonのライブラリの使い方についてはPythonライブラリ厳選レシピ(技術評論社)に大変お世話になりました。
djangoについては以下のサイトに特にお世話になりました。
- djangoproject.jp
- django公式ドキュメント ←一部日本語に翻訳されています。最近本家djangoproject.comにマージされたそうです
すったもんだしながら,何とか動くものができ,職場の同僚に見せて修正,というのを繰り返してひとまず完成しました。
Cloud9だとローカル開発と違って,URLを送るだけでアプリを見せることもできますし,同僚にもCloud9アカウントを持ってもらえば同じワークスペースを共有することも可能です。
余談になりますが,同僚に今回作成したアプリの説明をすることで,私のdjangoについての理解がぐっと進みました。
SQLite3からPostgreSQLへの移行
さて,せっかく完成したアプリですが,herokuにデプロイする前にもうひとつやっておくことがあります。
デフォルトではdjangoはSQLite3を使っています。そのままherokuにデプロイしてもとりあえずは動きますが,herokuのヘルプにこんな記述があります。
要するに,「とりあえず動くけど,仕組みの関係で最大24時間で消えちゃうよ」ということのようです。
ちなみにどれくらいで消えちゃうか,試しにやってみましたが1週間くらいたっても消えていないです。たまたまなのか,毎日「消えたかな?」と確認しているせいなのかわかりませんが,本番運用でそんなにドキドキしたくないので,素直にPostgreSQLに移行することにします。
ここではこちらの記事 3とこちらの記事4を参考にしました。
Cloud9のワークスペースにはPostgreSQLがもともとインストールされているので,新たにインストールする必要はありませんが,ステータスを見ると落ちているのでサービスを起動しておきます。
$ psql --version
psql (PostgreSQL) 9.3.11
$ sudo service postgresql status
9.3/main (port 5432): down
$ sudo service postgresql start
* Starting PostgreSQL 9.3 database server
...done.
PythonからPostgreSQLを使うためのpsycopg2ライブラリをインストールします。
$ sudo pip3 install psycopg2
次にPostgreSQLにログインします。sudo が2つということにご注意ください。
$ sudo sudo -u postgres psql
PostgreSQLのコンソールでログイン用のユーザー(ここではmyuser)を作ります。
postgres=# CREATE ROLE myuser LOGIN;
CREATE ROLE
postgres=# \password myuser
Enter new password:
Enter it again:
アプリで使うデータベース(ここではabc)を作成します。Cloud9では最後のTEMPLATE template0
をつけないとnew encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
と怒られるのですがどうしたらよいかわからずしばらく悩みました。
postgres=# CREATE DATABASE abc OWNER myuser ENCODING 'UTF8' TEMPLATE template0;
CREATE DATABASE
postgres=# \q
これでPostgreSQL側の準備はできました。
続いてdjangoプロジェクト(c9_abc)フォルダのsettings.pyを編集します。
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
#}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'abc',
# The following settings are not used with sqlite3:
'USER': ’myuser',
'PASSWORD': 'your_password_here',
'HOST': '127.0.0.1',
'PORT': 5432,
}
}
最後の手順は少しはまりました。
参考にした記事ではどちらもpython manage.py syncdb
でOKって書いてあるのですが,django1.9のリリースノートにThe syncdb command is removed.
とあり,もはや使えない機能になっています。
調べてみると,django1.8の公式ドキュメントに記載があり,syncdb
はmigrate
のエイリアスで,違いとしてはスーパーユーザーを作るステップが入っていることのようです。ということは,
$ python manage.py migrate
$ python manage.py createsuperuser
でOKですね。
これで移行は完了したはずです。念のためアプリがちゃんと動くか確認しておきましょう。
herokuへのデプロイ
もともとherokuが提供しているテンプレートなので,herokuにPythonのバージョンやインストールするライブラリを指示するファイル(runtime.txtとrequirements.txt)はルートフォルダに作成されています。
しかしherokuもデフォルトでは Python2.7なので,runtime.txtを修正します。
[runtime.txt]
python-3.4.3
次にrequirements.txtも更新します。
$ pip3 freeze > requirements.txt
ただしこのままでは,Cloud9のPython3の環境に入っているライブラリがすべて盛り込まれてしまいますので,内容を確認して不要なライブラリの行は削除してしまいましょう。
最初にvenvなどで環境を切っていれば,不要なライブラリの行を削除する作業は不要です。ライブラリの依存関係があったりするので,ちゃんとやりたい人は最初に環境を切りましょう。
続いてheroku toolkitをインストールします。
$ wget -O- https://toolbelt.heroku.com/install-ubuntu.sh | sh
インストールが完了したらさっそくherokuにログインします。
$ heroku login
アプリ開発の作業でgitリポジトリを作っていなかった人は作成します。
$ git init
$ git add -A
$ git commit -m 'initial commit'
heroku上にアプリのリポジトリを作成します。下の例ではアプリ名としてmyherokuapp
とつけています。これをつけなくてもherokuが自動で割り当ててくれますが20文字くらいの長い名前になります。
$ heroku create myherokuapp
続いていよいよデプロイします。
$ git push heroku master
Counting objects: 130, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (121/121), done.
Writing objects: 100% (130/130), 1.91 MiB | 726.00 KiB/s, done.
Total 130 (delta 52), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.4.3
remote: $ pip install -r requirements.txt
remote: Collecting Django==1.9.4 (from -r requirements.txt (line 1))
remote: Downloading Django-1.9.4-py2.py3-none-any.whl (6.6MB)
(中略)
remote: https://myherokuapp.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.
To https://git.heroku.com/myherokuapp.git
* [new branch] master -> master
しばらく待っていると上のような感じでデプロイが完了します。エラーになった人はログやエラーメッセージを確認して,必要な修正をお願いします。
さあもう一息です。heroku上でデータベースの初期化とスーパーユーザーの作成をおこないます。
$ heroku run python manage.py migrate
$ heroku run python manage.py createsuperuser
デプロイの途中で表示されたアプリのurl(上の例ではhttps://myherokuapp.herokuapp.com/
)を開いてみましょう。
問題なく動きましたか?そうしたらdjangoのデバッグモードを切っておきましょう。
Cloud9上でsettings.pyを編集します。
# DEBUG=True
DEBUG=False
この修正をherokuに反映します。
$ git add .
$ git commit -m 'Debug mode off'
$ git push heroku master
今後も修正したらこの3行(コミットコメントは適宜変えますが)を繰り返し使うことになりますので覚えておきましょう。
以上になります。
勘違いしている点,間違っている点等ありましたらご遠慮なく編集リクエスト等でお知らせください。よろしくお願いします。
この記事は@hirokikyさん作のPileMdで書きました
参考記事
-
Writing a Python App https://community.c9.io/t/writing-a-python-app/1609 ↩
-
How to deploy a Django project in Cloud9 to Heroku http://matthewstibbard.com/2016/01/15/how-to-deploy-a-django-project-in-cloud9-to-heroku/ ↩
-
PostgreSQLとDjangoでデータベースを作る https://sites.google.com/site/pcchatnetoiles/home/postgresql/postgresqldjango ↩
-
djangoでsqlite3からpostgreSQLに移行してみた。 http://freedom-man.com/blog/django_from_sqlite3_to_postgresql/ ↩