Django
Git
Heroku
python3

Python Djangoでherokuにデプロイしてみた

はじめに

PythonのWebアプリフレームワークDjangoを使ってherokuへのデプロイまでをやってみた。

初期設定

1.Python3系のインストールを確認する

・ バージョンを確認する
python --version
・pythonがどこにおいてあるか確認する
which python
※macには2系がデフォルトで搭載されていますが2系は廃止されるので3系をインストールしましょう
※pythonインストールがまだだったら以下のサイトなどを参考にインストールしてみましょう
https://qiita.com/ms-rock/items/6e4498a5963f3d9c4a67

2.Djangoのインストール

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

・django-toolbeltのインストール

terminal
(env) $ pip3 install django-toolbelt
(env) $ pip3 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  

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で書き出して、新しい環境を作る必要があります。

python3.6 -m venv (任意の環境名)

(例)
・venv環境を作成する

terminal
$ python3.6 -m venv env
$

・venv環境に切り替える

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

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

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

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

terminal
(env)$ pip install Django==2.0.6
(env)$ pip list
Django (2.0.6)
pip (9.0.1)
pytz (2018.4)
setuptools (28.8.0)

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

terminal
(env)$ deactivate
$ 

5.開発サーバーを起動する

・manage.pyがおいてあるディレクトリに移動し、runserverコマンドを使用する
(env) $ python manage.py runserver

・以下の画面が出れば成功
スクリーンショット 2017-12-11 23.31.38.png
・終了するにはcontroll+Cする

6.プロジェクトの日本語設定

sample_app/setting.pyの言語コードとタイムゾーンを変更する。

terminal
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

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

7.データベースの設定

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

terminal
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

8.管理用テーブルを作成する

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

・INSTALLED_APPSの設定確認

terminal
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 version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
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 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 sessions.0001_initial... OK

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

terminal
(env) $ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
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   

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内に、アプリケーションの構成クラスであるItemConfigクラスが作成される。sample_app/setting.pyのINSTALLED_APPSにAppConfigを追加する。

terminal
# 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を以下のように編集する

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) $ 

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

terminal
(env) $ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
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          

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

バージョン管理ツールの導入

ソースコードの管理にGitを用いる

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アカウントを用意する

こちらからアカウントを作成する

20.アプリをHerokuで使える設定をする

こちらからHeroku CLIをインストールする

・sample_app/setting.pyに以下を上書きする。

terminal
# Allow all host headers
ALLOWED_HOSTS = ['*']
terminal
# Static asset configuration
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)

・sample_app/setting.pyに以下を追加する。

terminal
# Parse database configuration from $DATABASE_URL
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES['default'].update(db_from_env)

# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

・sample_app/wsgi.pyを以下に書き換える

terminal
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/2.0/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.6.3" > 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

終わりに

今回はPython Djangoを使ってGitやデータベース作成などのWebアプリケーションに必要な知識を踏まえつつ、herokuへのデプロイまでやってみた。
今後はより具体的なアプリケーションの作成などを記事にしていきたい。