utamaro’s blog

誰かの役に立つ情報を発信するブログ

Djangoをherokuにデプロイする

herokuの用意

  • アカウント作成 f:id:miyaji-y26:20180926003338p:plain
  • アプリケーションを作成 f:id:miyaji-y26:20180926003406p:plain

f:id:miyaji-y26:20180926003422p:plain

開発環境を用意する

macを対象にしています。
brewをインストールしていることが前提です。

herokuをインストールする

brew install heroku

以上です。

herokuのコマンド

ログインする

heroku login

herokuのアプリ一覧を取得する

heroku apps

gitを使ってデプロイするための準備をする

heroku git:remote -a sample

これをすると、git remote add origin <url>を実行したような動作をする。

pushする際は↓のようにする。

git push heroku master

実行すると、herokuでビルドされる。

herokuでログを確認する

heroku logs --tail

herokuでdynoを起動する

heroku ps:scale web=1

停止する場合は0にセットする。

webというのは、Procfileに書いているwebに該当する。

web: gunicorn DjangoForHeroku.wsgi

herokuの再起動

heroku restart

herokuのdynoをstop

heroku ps:stop <web>

これをやると、がidle状態になる。 停止するわけではないため、dynoを止める場合はscaleを使用すること。

ビルドパックが設定されていないというエラーが出た場合

heroku buildpacks:set heroku/python

↑はpythonのビルドパックを設定している。 使えるビルドパックは(https://devcenter.heroku.com/articles/buildpacks)にかかれています。

ローカルで動作確認する場合

heroku local

Djangoの場合は事前にcollectstaticを実行しておくこと。
(herokuのリモートで自動実行されているものを、手動でやる必要がある)

herokuのpostgresqlに接続する

heroku pg:psql

Djangoをherokuにデプロイ

  • Djangoのベースとなるアプリを作る
    • django-admin startproject DjangoForHeroku .で十分
    • ライブラリをインストールしたり
    • heroku用の設定を書いたり

プロジェクトを作成する

django-admin startproject DjangoForHeroku .

ライブラリをインストールする。

pip listで表示されたものをすべて載せています)

certifi (2018.8.24)
chardet (3.0.4)
defusedxml (0.5.0)
dj-database-url (0.5.0)
Django (2.1)
djangorestframework (3.8.2)
gunicorn (19.9.0)
idna (2.7)
Jinja2 (2.10)
jinjasql (0.1.7)
MarkupSafe (1.0)
mysqlclient (1.3.13)
pip (9.0.1)
psycopg2 (2.7.5)
psycopg2-binary (2.7.5)
python3-openid (3.1.0)
pytz (2018.5)
requests (2.19.1)
setuptools (28.8.0)
six (1.11.0)
urllib3 (1.23)
whitenoise (4.1)

インストールが完了したらheroku用の設定ファイルを用意します。

また、Djangoの構造については↓を参考にしてください。 utamaro.hatenablog.jp

herokuに必要なファイルを作成します。

manage.pyがあるディレクトリに作成します。

touch Procfile runtime.txt

Procfile

release: python manage.py migrate --settings=DjangoForHeroku.settings.product
web: gunicorn DjangoForHeroku.wsgi

webというプロセスを、gunicornを使って、○.wsgiを実行する。

あとから知ったのですが、release phaseというものがあり、deploy時のコマンドを設定できるみたいです。

これを知るまではheroku run python ...ryというように実行してました。

runtime.txt

python-3.6.6

settings.pyを編集する。

settingsパッケージを作成して、以下の構造にします。

settings
├── __init__.py
├── base.py
├── local.py
└── product.py

検索してヒットする情報ではsettings.py上でlocal-setting.pyがある場合に~といったコードを書いているのを見かけます。

セッティングファイルは分けておいたほうが何かと便利なので、分けるのがおすすめです。

base.pyを編集します。

DEBUG = False

ALLOWED_HOSTS = ['*']
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # ← を追加します。
    'django.contrib.sessions.middleware.SessionMiddleware',
    # ... ry
]

# ↓ をコメントアウトします。消してもいいです。この設定は、local.pyとproduct.pyに書きます。
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.postgresql_psycopg2',
#         'NAME': 'database',
#         'USER': 'root',
#         'PASSWORD': 'pass',
#         'HOST': '127.0.0.1',
#         'PORT': '5432',
#         'AUTOCOMMIT': True,
#     }
# }

# ↓ /static/css/A.cssとか、/static/js/A.jsのように読み込まれます。
STATIC_URL = '/static/'

# collectstaticを実行したとき、静的ファイルがstaticfilesにまとめられます。
# herokuでビルドする際にデフォルトでcollectstaticが実行されます。
STATIC_ROOT = 'staticfiles'

# 自分で作った静的ファイルのディレクトリをSTATIC_ROOTにまとめたいときに設定します。
# ↓の場合だとassets/static以下のファイルがstaticfilesにまとめられます。
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "assets/static/"),
)

# httpをhttpsにリダイレクトさせる設定です。
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

local.pyを編集します。

from DjangoForHeroku.settings.base import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'sample',
        'USER': 'sample_admin',
        'PASSWORD': 'sample_password',
        'HOST': '127.0.0.1',
        'PORT': '5432',
        'AUTOCOMMIT': True,
    }
}

DEBUG = True

ALLOWED_HOSTS = []

product.pyを編集します。

from DjangoForHeroku.settings.base import *
import dj_database_url

# herokuの環境変数でDATABASEが更新される。
db_from_env = dj_database_url.config()
DATABASES['default'].update(db_from_env)

wsgi.pyを編集する

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoForHeroku.settings.product')

application = get_wsgi_application()

Procfileを作成したときに↓のように書いたと思います。

web: gunicorn DjangoForHeroku.wsgi

このときのwsgiが対象のファイルです。

requirements.txtを作成する

初めてやったときに↓のコマンドを実行してなくて、ビルドに失敗しました。

pip freeze > requirements.txt

ちなみにですが、pip freeze > rpip.txtもだめでした。

requirements.txtと打つのが面倒で、rpip.txtと省略してたのがダメみたいです。

manage.pyを編集する

↓で、起動時にはbaseが読み込まれます。

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoForHeroku.settings.base')
    try:
        from django.core.management import execute_from_command_line
    # ... ry

wsgiで実行される際は、productで上書きされます。

.gitignoreを作成する

余分なファイルはcommitに含めないようにします。

.idea
.python-version
*.egg-info
*.pot
*.py[co]
__pycache__
MANIFEST
*/django.log
staticfiles

これで準備完了です。

(思い出しながら記事を書いているので、もしかしたらエラーが出るかもしれません。エラーが出たらログを確認してみてくださいmm)

はじめてのデプロイ

git add ./
git commit -m "first deploy."
git push heroku master

以上です。

openコマンドを使って、動作を確認してみましょう。

デフォルトのブラウザが開かれます。

heroku open