LoginSignup
0
0

More than 1 year has passed since last update.

Github管理下のDjangoプロジェクト(mysql使用)をherokuに構築する(Part1)

Last updated at Posted at 2021-09-12

2023/02/01現在、herokuは無料プランの提供を終了しており、有料プランのみの提供となっています。

無料でサーバーを立てられるherokuDjangoを使ったアプリケーションを構築しようとしたところ、たくさんのトラップに引っかかったので、備忘録としてまとめることにしました。

0. 前置き

目的

  1. herokuにDjangoアプリケーションを立てたい
  2. リポジトリはGitHubに置いておきたい
  3. Djangoで使うDBはMySQLがいい

今回は以上の目的を達成するための流れを一通り説明します。

前提知識

  • ターミナルの基本操作ができること
  • pythonの環境を整えていること
  • djangoの基本的な使い方を知っていること

ローカル環境

環境 項目
OS macOS BigSur 11.5.2
Python 3.9.7, venv(環境管理), pip(パッケージ管理)
Django 3.2.7
heroku CLI heroku/7.59.0 darwin-x64 node-v12.21.0

その他

  • プロジェクト名は[heroku-pj]または[heroku_pj]と記載しています。各自の設定に置き換えてください
  • herokuコマンドに必須の-aオプションは省略しているので、各自で補完してください

1. Pythonの設定

まずはローカルの環境を整えます。

1-1. 仮想環境(venv)の用意

※Pythonの環境整備は宗派が分かれるので参考程度で。

zsh
% python -m venv .venv
% source .venv/bin/activate
# 警告がしつこく出るのでupgradeする
% pip install -U pip

1-2. 必要なライブラリのインストール

必要なライブラリは以下の通りです。(バージョンは執筆当時の最新版です)

requirements.txt
asgiref==3.4.1
dj-database-url==0.5.0
Django==3.2.7
django-heroku==0.3.1
gunicorn==20.1.0
mysql==0.0.3
mysqlclient==2.0.3
psycopg2==2.9.1
pytz==2021.1
sqlparse==0.4.1
whitenoise==5.3.0

1-3. djangoプロジェクトの作成

今回はプロジェクトのルートをgit管理したいので、作ります。
アプリケーションは今回は作らなくても良いです。

zsh
% django-admin startproject [heroku_pj]
% cd [heroku_pj]

1-4. 各種ファイルの作成

.gitignore

必要なものがあれば適宜追記してください。

.gitignore
__pycache__
.DS_Store
local.py
db.sqlite3

requirements.txt

以下のコマンドで生成します(上記のrequirements.txtをコピペしても良いですが、最新版にしておくことをお勧めします)

zsh
% pip freeze > requirements.txt

Procfile

herokuのビルドに必要です。

Procfile
web: gunicorn heroku_pj.wsgi --log-file -

runtime.txt

heroku上のPythonバージョン指定に必要です。
バージョンはこちらのページで最新の対応状況を確認してください。

runtime.txt
python-3.9.7

1-5. settings.pyの分離

開発環境(ローカル)と本番環境(heroku上)ではデータベース等の設定が異なりますので、ファイルを分離しておいた方が良いです。
本記事では分離することを前提としてコードを書いているので、分離しない人は1-5, 1-6をスキップしてください。

1-5-1. フォルダ構造

  • [heroku_pj]-ルート
    • [heroku_pj]
      • settings
        • __init__.py
        • base.py
        • local.py
        • production.py
      • __init__.py
      • asgi.py
      • urls.py
      • wsgi.py
    • manage.py
    • (以下省略)

1-5-2. base.py

デフォルトのsettings.pyから以下の項目を除きます。

  • DEBUG, ALLOWED_HOSTS, SECRET_KEY, DATABASES
    • SECRET_KEYは中身をコピー&メモしておくこと(あとで使います)

また、以下の項目を変更しておきます(差分のある項目のみ表示)

[heroku_pj]/settings/base.py
# settingsの階層が1つ深くなるのでさらに親ディレクトリを取る
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# whitenoiseのミドルウェアをこの位置に追加する
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    (省略)
]

LANGUAGE_CODE = 'ja-jp'

TIME_ZONE = 'Asia/Tokyo'

# 以下はwhitenoiseとcollectstaticに関連して必要な設定
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

1-5-3. local.py

BASE_DIRbase.pyで定義しているので明示する必要はありませんが、気持ち悪い人は書き加えてください。

[heroku_pj]/settings/local.py
import os

from .base import *


DEBUG = True

# ここは各自でよしなにしてください
ALLOWED_HOSTS = ['127.0.0.1',]

SECRET_KEY = '[元のSECRET_KEYをそのままコピペ]'

#settings.pyからそのままコピー
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

1-5-4. production.py

BASE_DIRについては同上。
また、多くの値を環境変数から取得していますが、その設定については後述します。

[heroku_pj]/settings/production.py
import os
import django_heroku
import dj_database_url

from .base import *


DEBUG = False

# ['*']でもいい
ALLOWED_HOSTS = ['127.0.0.1', '.herokuapp.com']

# 秘密鍵はファイルに書かない
SECRET_KEY = os.environ['SECRET_KEY']

DATABASES = {
    'default': {
        # localと異なり、mysqlのエンジンを用いる
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            # これを設定しないとMySQLのWARNINGが出る
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
        # 以下はあとで値を設定する
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USERNAME'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': os.environ['DB_HOSTNAME'],
        'PORT': os.environ['DB_PORT'],
    }
}

# 補足参照
db_from_env = dj_database_url.config(conn_max_age=600, ssl_require=False)
DATABASES['default'].update(db_from_env)
django_heroku.settings(locals(), databases=False)
  • MySQLを使わず(heroku標準の)PostgreSQLを使用したい場合、DATABASES['default']['ENGINE']の値は以下に変更になります

    • 'django.db.backends.postgresql_psycopg2'
  • dj_database_url.config()において、ssl_require=Falseを指定しないとdjango_heroku.settings()でエラーが出ます

1-6. manage.py/wsgi.pyの書き換え

開発環境と本番環境で適切なsettingsを読み込むために必要です。

1-6-1. manage.py

書き換え前(抜粋、main関数の最初)

manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[heroku_pj].settings")

書き換え後

manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[heroku_pj].settings.local")

1-6-2. [heroku_pj]/wsgi.py

書き換え前(抜粋)

manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[heroku_pj].settings")

書き換え後

manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[heroku_pj].settings.production")

ここまで長くなったので続きは別記事へ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0