#はじめに
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のインストール
$ 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ディレクトリが生成される
.
├── 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環境を作成する
$ python -m venv env
$
venv環境に切り替える
$ source ./env/bin/activate
(env)$
pip list
でパッケージを確認する
(env)$ pip install --upgrade pip
(env)$ pip list
pip
setuptools
最新版のDjangoをインストールし直す
(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
(env)$ deactivate
$
##5.開発サーバーを起動する
manage.pyがおいてあるディレクトリに移動し、runserverコマンドを使用する
(env) $ python manage.py runserver
終了するにはcontroll+Cする
##6.プロジェクトの日本語設定
sample_app/settings.pyの言語コードとタイムゾーンを変更する。
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
##7.データベースの設定
djangoではデフォルトでSQLiteが利用されています。
データベースの設定はsample_app/settings.pyのDATABASESでされています。
DATABASESの設定確認
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
##8.管理用テーブルを作成する
Djangoではユーザー管理、セッション管理、管理サイトなどの機能がデフォルトで用意されている。
またデータベースのテーブル作成、変更を行うためのマイグレーション機能を提供している。
INSTALLED_APPSの設定確認
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
テーブルが空であることを確認する
(env) $ python manage.py dbshell
sqlite> .table
sqlite> .q
マイグレーションの実行、下記コマンドを実行する。
(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) %
テーブルができてることを確認する
(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ディレクトリが生成される
.
├── __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を追加する。
# 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で管理ユーザーを作成する
(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
にアクセスする
(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で作成したユーザー名とパスワードでログインする。
テーブルを生成する
##12.モデルの作成
app/models.pyを以下のように編集する
taskというモデルを定義しています
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コマンドでマイグレーションファイルを作成する
(env) $ python manage.py makemigrations
Migrations for 'app':
app/migrations/0001_initial.py
- Create model Task
migrateコマンドでマイグレーションを実行する
(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というテーブルができてることを確認する
(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に以下を入力
from django.contrib import admin
# Taskモデルをインポート
from .models import Task
# 管理サイトへのモデルを登録
admin.site.register(Task)
サーバーを起動して管理サイトを確認する。モデルが追加されていれば成功。
#バージョン管理ツールの導入
14~18は分かりきっている人は飛ばして問題ない
##14.Gitの設定
以下のサイトからGitをインストールする
https://git-scm.com/downloads
ユーザー名とメールアドレスの設定をする
(env) $ git config --global user.email (メールアドレス)
(env) $ git config --global user.name (ユーザー名)
##15.リポジトリの作成
git init (リポジトリ名)
で指定した名前のリポジトリを作成します。
今回は既にリポジトリを作成しているのでgit init
だけします。
(env) $ git init
Initialized empty Git repository in
/Users/ユーザー名/PycharmProjects/sample_app/.git/
##16.sshキーを生成、登録する
githubと連携するために以下のコマンドでsshキーを生成する
$ 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
以下のコマンドを実行します。
$ pbcopy < ~/.ssh/id_rsa.pub
id_rsa.pubの中身がコピーされる。
github SSH keysに登録する。
「New SSH Key」からTitle(任意)とKey(コピーしたもの)を入力し、登録する。
##17.New Repositoryからリモートリポジトリを作成、リモートリポジトリのURIをローカルに設定する
New Repositoryからリポジトリを作成
作成したリモートリポジトリの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を定義しておく必要があるが、どこからアクセスされても問題ないアプリなら*と指定しておけば良い。
# Allow all host headers
ALLOWED_HOSTS = ['*']
HerokuではDjangoで設定されているsqlite3では動作せず、
Herokuのデフォルトのpostgresqlが使われるように設定する。
dj_database_urlはdjango-toolbeltに含まれている。
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES['default'].update(db_from_env)
dj-staticを読み込んでget_wsgi_applicationをラップしている。
GunicornなどのWSGIサーバーを使用して本番環境から静的ファイルを適用するのに必要。
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
(env) $ echo "web: gunicorn sample_app.wsgi --log-file -" > Procfile
(env) $
runtime.txtを作成する。
runtime.txtはPythonのバージョンを指定する役割を持つ。
(env)$ echo "python-3.8.1" > runtime.txt
(env)$
requirements.txtを作成する。
requirements.txtはpipの依存関係を表す
(env)$ pip3 freeze > requirements.txt
(env)$
##22.Herokuアプリを作成する
以下のコマンドを実行する。
(env)$ heroku create
・・・
(env)$
Heroku環境変数の設定
https://devcenter.heroku.com/articles/django-assets
(env)$ heroku config:set DISABLE_COLLECTSTATIC=1
(env)$
作成したアプリ情報を確認する
(env)$ heroku apps
・・・
(env)$
作成したアプリを削除したい場合(--confirmは確認無しで削除するためのコマンド)
$ heroku apps:destroy --app (app名) --confirm (app名)
(env)$
Herokuにプッシュする
(env)$ git add .
(env)$ git commit -m "Herokuの設定"
(env)$ git push heroku master
Herokuでマイグレーションする
(env)$ heroku run python manage.py migrate
(env)$
Herokuの管理サイトユーザーを作成する
(env)$ heroku run python manage.py createsuperuser
・
・
・
Username (leave blank to use ''):
Email address:
Password:
Password (again):
Superuser created successfully.
(env)$
Herokuを開いて確認する
(env)$ heroku open
(env)$
https://(app名).herokuapp.com/admin/login/?next=/admin/
成功していればウェブサーバー上に以下のサイトが表示される。作ったユーザーとパスワードでログインもできる。
参考
herokuでのpythonプロジェクトのベストプラクティスはこちらのリポジトリが参考になる
https://github.com/heroku/python-getting-started