75
78

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python DjangoでHerokuにデプロイする

Last updated at Posted at 2017-12-20

#はじめに
PythonのWebアプリフレームワークDjangoを使ってherokuへのデプロイまでをやってみる。

#初期設定
##1.Python3系のインストールを確認する
バージョンを確認する
python --version

pythonがどこにおいてあるか確認する
which python

※macには2系がデフォルトで搭載されていますが2系は廃止されるので3系をインストールしましょう
※pythonインストールがまだだったら以下の記事などを参考にインストールしてみましょう
https://qiita.com/ms-rock/items/72b8f1abc661c539bb09

##2.Djangoのインストール
Djangoの公式ページで最新版を確認してインストールできるが、
django-tool-beltをインストールすればデプロイに必要なものも含めて一括インストールできる。

django-toolbeltのインストール

terminal
$ pip install django-toolbelt
$ pip list
Package         Version
--------------- -------
dj-database-url 0.5.0  
dj-static       0.0.6  
Django          2.0.6  
django-toolbelt 0.0.1  
gunicorn        19.8.1 
pip             10.0.1 
psycopg2        2.7.4  
pytz            2018.4 
setuptools      28.8.0 
static3         0.7.0  

トラブルシューティング
psycopg2のインストールで失敗することがあるが、以下の記事の対処方法で解決できた
https://dev.classmethod.jp/articles/mac-psycopg2-install/

##3.プロジェクトの作成
Djangoがインストールされるとdjango-adminコマンドが使用できるようになります。
django-admin startproject (アプリ名)

sample_appというプロジェクトを作ってみる
$ django-admin startproject sample_app

以下のような構成のsample_appディレクトリが生成される

terminal

.
├── manage.py
└── sample_app
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

##4.venv環境を作成する
###venvとは?
python3で提供されている仮想環境を提供するモジュール。
プロジェクトごとにインストールするパッケージを切り替えたいときなどに用いられる。
※同様のPython環境管理ツールにvirtualenvというコマンドもある。
これはPython2系で必要なものであり、Python2系で作る必要がある場合はこちらになるが多くの場合は3系で作るので必要ないと思われる。
※venvで作った環境を移動させると壊れるので、環境の場所を変えたい場合はpip freezで書き出して、新しい環境を作る必要があります。

python -m venv (任意の環境名)

(例)
venv環境を作成する

terminal
$ python -m venv env
$

venv環境に切り替える

terminal
$ source ./env/bin/activate
(env)$ 

pip listでパッケージを確認する

terminal
(env)$ pip install --upgrade pip
(env)$ pip list
pip
setuptools

最新版のDjangoをインストールし直す

terminal
(env)$ pip list
Package    Version
---------- -------
pip        20.2.4
setuptools 49.2.1
(env)$ python -m pip install Django
(env)$ pip list
Package    Version
---------- -------
asgiref    3.2.10
Django     3.1.2
pip        20.2.4
pytz       2020.1
setuptools 49.2.1
sqlparse   0.4.1

venv環境の無効化する場合はdeactivate

terminal
(env)$ deactivate
$ 

##5.開発サーバーを起動する
manage.pyがおいてあるディレクトリに移動し、runserverコマンドを使用する
(env) $ python manage.py runserver

以下の画面が出れば成功
127.0.0.1_8000_.png

終了するにはcontroll+Cする

##6.プロジェクトの日本語設定
sample_app/settings.pyの言語コードとタイムゾーンを変更する。

sample_app/settings.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

サーバーを起動し、日本語の画面に更新されていれば成功
スクリーンショット 2017-12-11 23.48.41.png

##7.データベースの設定
djangoではデフォルトでSQLiteが利用されています。
データベースの設定はsample_app/settings.pyのDATABASESでされています。
DATABASESの設定確認

sample_app/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

##8.管理用テーブルを作成する
Djangoではユーザー管理、セッション管理、管理サイトなどの機能がデフォルトで用意されている。
またデータベースのテーブル作成、変更を行うためのマイグレーション機能を提供している。

INSTALLED_APPSの設定確認

sample_app/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

テーブルが空であることを確認する

terminal
(env) $ python manage.py dbshell
sqlite> .table
sqlite> .q

マイグレーションの実行、下記コマンドを実行する。

terminal
(env) % python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
(env) % 

テーブルができてることを確認する

terminal
(env) $ python manage.py dbshell
sqlite> .table
auth_group                  auth_user_user_permissions
auth_group_permissions      django_admin_log          
auth_permission             django_content_type       
auth_user                   django_migrations         
auth_user_groups            django_session            
sqlite> 

##9.アプリケーションを作成する
プロジェクトとその初期設定は完了したので、実際の機能や画面などを定義してるアプリケーション本体を作成する。

appアプリケーションの作成
(env) $ python manage.py startapp app

以下のようなappディレクトリが生成される

terminal
.
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

アプリケーションを作成するとapp/apps.py内に、アプリケーションの構成クラスであるAppConfigクラスが作成される。sample_app/setting.pyのINSTALLED_APPSにAppConfigを追加する。

sample_app/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app.apps.AppConfig', # AppConfigを追加
]

#管理サイト
##10.管理ユーザーの作成
createsuperuserで管理ユーザーを作成する

terminal
(env) $ python manage.py createsuperuser
Username (leave blank to use 'ユーザー名'): (任意のユーザーネームを入力する)
Email address: (任意のメールアドレスを入力する)                 
Password: (パスワードを入力する)
Password (again): (パスワードを再入力)
Superuser created successfully.

##11.開発サーバー起動
サーバーを起動し、http://127.0.0.1:8000/adminにアクセスする

terminal
(env) $ python manage.py runserver
Django version 2.0.6, using settings 'sample_app.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

うまく行っていれば以下の画面が出力される。11で作成したユーザー名とパスワードでログインする。
スクリーンショット 2017-12-12 7.38.01.png

管理サイトへのログインが成功する
スクリーンショット 2017-12-12 7.40.34.png

#モデルの定義

テーブルを生成する

##12.モデルの作成
app/models.pyを以下のように編集する
taskというモデルを定義しています

app/models.py
from django.db import models


class Task(models.Model):
    name = models.CharField('タスク名', max_length=255)
    created_date = models.DateTimeField('作成日時', auto_now_add=True)
    update_date = models.DateTimeField('更新日時', auto_now=True)

    def __str__(self):
        return self.name

makemigrationコマンドでマイグレーションファイルを作成する

terminal
(env) $ python manage.py makemigrations
Migrations for 'app':
  app/migrations/0001_initial.py
    - Create model Task

migrateコマンドでマイグレーションを実行する

terminal
(env) $ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, app, auth, contenttypes, sessions
Running migrations:
  Applying app.0001_initial... OK
(env) $ 

app_taskというテーブルができてることを確認する

terminal
(env) $ python manage.py dbshell
sqlite> .table
app_task                    auth_user_user_permissions
auth_group                  django_admin_log          
auth_group_permissions      django_content_type       
auth_permission             django_migrations         
auth_user                   django_session            
auth_user_groups          
sqlite>

##13.管理サイトへモデルを登録
app/admin.pyに以下を入力

app/admin.py
from django.contrib import admin

# Taskモデルをインポート
from .models import Task

# 管理サイトへのモデルを登録
admin.site.register(Task)

サーバーを起動して管理サイトを確認する。モデルが追加されていれば成功。
スクリーンショット 2017-12-12 8.41.35.png

#バージョン管理ツールの導入
14~18は分かりきっている人は飛ばして問題ない

##14.Gitの設定
以下のサイトからGitをインストールする
https://git-scm.com/downloads

ユーザー名とメールアドレスの設定をする

terminal
(env) $ git config --global user.email (メールアドレス)
(env) $ git config --global user.name (ユーザー名)

##15.リポジトリの作成
git init (リポジトリ名)で指定した名前のリポジトリを作成します。
今回は既にリポジトリを作成しているのでgit initだけします。

terminal
(env) $ git init
Initialized empty Git repository in 
/Users/ユーザー名/PycharmProjects/sample_app/.git/

##16.sshキーを生成、登録する
githubと連携するために以下のコマンドでsshキーを生成する

terminal
$ ssh-keygen -t rsa -b 4096 -C (メールアドレス)
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/ユーザー名/.ssh/id_rsa): (エンターを押す)
・
・
・
$ tree
.
├── id_rsa
└── id_rsa.pub

以下のコマンドを実行します。

terminal
$ pbcopy < ~/.ssh/id_rsa.pub

id_rsa.pubの中身がコピーされる。
github SSH keysに登録する。
「New SSH Key」からTitle(任意)とKey(コピーしたもの)を入力し、登録する。

##17.New Repositoryからリモートリポジトリを作成、リモートリポジトリのURIをローカルに設定する
New Repositoryからリポジトリを作成

スクリーンショット 2017-12-12 11.18.22.png

作成したリモートリポジトリのURIをコピーして以下のコマンドを実行
$ git remote add origin (リモートリポジトリのSSH URI)

##18.git各種コマンド
差分ステータスを確認する
git status

変更をステージに上げる
git add .

コミットする
git commit -m "メッセージ"

ブランチを確認する
git branch

ブランチを切り替える
git branch (切り替え先ブランチ名)

リモートにプッシュする
git push -u origin master

プルする
git pull

#Herokuにデプロイする

##19.Herokuアカウントを用意する
Herokuアカウントがない場合はまずHerokuアカウントの作成をする
herokuコマンドを使うためHeroku CLIのインストールをする

##20.アプリをHerokuで使える設定をする
ALLOWED_HOSTSはWebシステムが起動することを許可するIPアドレスを指定する項目で、Herokuでは指定がないとDisallowedHostになってしまう。
IPを制限する必要があるならIPを定義しておく必要があるが、どこからアクセスされても問題ないアプリなら*と指定しておけば良い。

sample_app/settings.py
# Allow all host headers
ALLOWED_HOSTS = ['*']

HerokuではDjangoで設定されているsqlite3では動作せず、
Herokuのデフォルトのpostgresqlが使われるように設定する。
dj_database_urlはdjango-toolbeltに含まれている。

sample_app/settings.py
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES['default'].update(db_from_env)

dj-staticを読み込んでget_wsgi_applicationをラップしている。
GunicornなどのWSGIサーバーを使用して本番環境から静的ファイルを適用するのに必要。

sample_app/wsgi.py
import os

from dj_static import Cling
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sample_app.settings")

application = Cling(get_wsgi_application())

##21.デプロイに必要なファイルを作成する
Procfileを作成する。ProcfileはHeroku上で実行するコマンドを定義したファイルである。
Djangoとherokuのドキュメントを参考に以下のように入力する。

https://docs.djangoproject.com/ja/3.1/howto/deployment/wsgi/gunicorn/
https://devcenter.heroku.com/articles/django-app-configuration

terminal
(env) $ echo "web: gunicorn sample_app.wsgi --log-file -" > Procfile
(env) $

runtime.txtを作成する。
runtime.txtはPythonのバージョンを指定する役割を持つ。

terminal
(env)$ echo "python-3.8.1" > runtime.txt
(env)$ 

requirements.txtを作成する。
requirements.txtはpipの依存関係を表す

terminal
(env)$ pip3 freeze > requirements.txt
(env)$ 

##22.Herokuアプリを作成する
以下のコマンドを実行する。

terminal
(env)$ heroku create
・・・
(env)$

Heroku環境変数の設定
https://devcenter.heroku.com/articles/django-assets

terminal
(env)$ heroku config:set DISABLE_COLLECTSTATIC=1
(env)$

作成したアプリ情報を確認する

terminal
(env)$ heroku apps
・・・
(env)$

作成したアプリを削除したい場合(--confirmは確認無しで削除するためのコマンド)

terminal
$ heroku apps:destroy --app (app名) --confirm (app名)
(env)$

Herokuにプッシュする

terminal
(env)$ git add .
(env)$ git commit -m "Herokuの設定"
(env)$ git push heroku master

Herokuでマイグレーションする

terminal
(env)$ heroku run python manage.py migrate
(env)$

Herokuの管理サイトユーザーを作成する

terminal
(env)$ heroku run python manage.py createsuperuser
・
・
・
Username (leave blank to use ''): 
Email address: 
Password: 
Password (again): 
Superuser created successfully.
(env)$ 

Herokuを開いて確認する

terminal
(env)$ heroku open
(env)$ 

https://(app名).herokuapp.com/admin/login/?next=/admin/

成功していればウェブサーバー上に以下のサイトが表示される。作ったユーザーとパスワードでログインもできる。
スクリーンショット 2017-12-12 13.16.48.png

参考

herokuでのpythonプロジェクトのベストプラクティスはこちらのリポジトリが参考になる
https://github.com/heroku/python-getting-started

75
78
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
75
78

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?