Django デプロイ作業
この記事では「Djangoのデプロイ作業」の基本的な流れを「Virtual Box」を利用して行います。作業内容は以下の通りです。
ローカル側(開発環境側)での作業
- 「settings.py」を編集する
- 利用しているパッケージを「requirements.txt」に出力する
- Githubへプロジェクトをpushする
サーバー側(本番環境側)での作業
- Virtual BoxにRocky Linux を準備する
- DBMS(この記事ではPostgreSQL)のインストールと設定
- gitのインストールと設定
- Githubからプロジェクトをクローンする
- python仮想環境の準備
- gunicornのインストールと設定
- Webサーバー(この記事ではnginx)のインストールと設定
ローカル側(開発環境側)での作業
ローカル側では次の作業を行います。
- 「settings.py」の編集
- 「requirements.txt」の出力
- Githubへのプロジェクトのpush
settings.pyの編集
プロジェクトフォルの中にあるsettings.pyですが、デプロイ前には次の処理を行っておきます。
- プロジェクトフォルダ内に新しく「settings」フォルダを準備する。
- 「開発環境用のsettings.py」を準備する。→この記事では「settings_develop.py」
- 「本番環境用のsettings.py」を準備する。→この記事では「settings_product.py」
- 「共通で利用できるsettings.py」を準備する→この記事では「base.py」
- 「settings」フォルダに「__init__.py」を作成する。
まずは、「settings.py」のあるディレクトリに「settings」ディレクトリを準備します。その後、準備した「settings」ディレクトリに「settings.py」を移動して名前を「base.py」に変更します。
続けて、「settings_develop.py」、「settings_product.py」、「__init__.py」の3つのファイルを「settings」フォルダ内に新規で準備します。
(__pycache__ディレクトリは作業中に自動的に生成されるものなので開発者が作成したりはしません。)
「__init__.py」ファイルには次のように入力します。
# 本番環境
from .settings_product import *
try:
# 開発環境
from .settings_develop import *
except:
pass
base.py(もとのsettings.py)から開発環境用の「settings_develop.py」と本番環境用の「settings_product.py」へ「SECRET_KEY」「DEBUG」「ALLOWED_HOSTS」「DATABASES」を切り取り、貼り付けます。この記事では少し編集を加えたため若干の違いがありますが、本来なら、どちらにも同じ状態が作成されています。
from .base import *
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-***この部分はデフォルトの鍵が入っています。***'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
#この部分には開発環境でのIPアドレスを入れています。
ALLOWED_HOSTS = ["127.0.0.1", "192.168.2.139"]
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
もう一つのファイル「settings_product.py」を次のように編集します。
from .base import *
# SECURITY WARNING: keep the secret key used in production secret!
# 何も入力しません。
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
#この部分には本番環境でのIPアドレスを入れます。現在は「*」としています。
ALLOWED_HOSTS = [" * "]
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
「base.py」の中にある「BASE_DIR」の箇所を次のように編集します。
(編集前)BASE_DIR = Path(__file__).resolve().parent.parent
(編集後)BASE_DIR = Path(__file__).resolve().parent.parent.parent
以上で「settings.py」の編集は終了です。
requirements.txtの作成
開発しているDjangoプロジェクトで利用しているパッケージのメモをとります。これにはプロジェクトフォルダをカレントディレクトリとして次のコマンドを入力します。
pip freeze > requirments.txt
requirments.txtが生成されます。中身はプロジェクトで利用している全てのパッケージが一行ごとに記載されています。
gitの作業
以下の作業が済んでいる前提で記事を進めています。
Gitのインストール
https://howahowablog.com/git-install/Gitの設定
https://howahowablog.com/git-config/Githubへプロジェクトをpushする前に、pushの対象から外すファイルを.gitignoreに指定します。(下は参考)
「.gitignore」の中身は、こちらのサイトを利用して基本設定を自動生成して、個別に必要な部分のみ追記します。表示される検索ボックスに「Django」と入力して「作成する」をクリックします。
https://www.toptal.com/developers/gitignore
表示された内容を「Ctrl + A」で全選択して「Ctrl + C」でコピーします。コピーしたら、「.gitignore」ファイルへ「Ctrl + V」でペーストします。
追記したいディレクトリやファイルを入力します。(/authは開発中に個別の設定を行ったファイルを格納していました。/settings_develop.pyはローカル側で利用している情報なのでpushから除外しています。)
プロジェクトをgit initでgit管理下にします。(開発時にすでにGit管理下にしていればこの作業は必要ありません。)
git add .で「.gitignore」に記述されたファイル以外をステージングエリアへ追加します。ステージングエリアに追加されるとファイルの横のアルファベットが「U」から「A」に変わります。
Githubへのプロジェクトの追加
以下の作業が済んでいる前提で記事を進めています。
Githubの登録
https://howahowablog.com/github-account-registration/秘密鍵の作成方法とGithubへの秘密鍵の登録
https://howahowablog.com/connect-to-github-using-ssh/リモートリポジトリの作成
https://howahowablog.com/make-remoto-repository/今回のリモートリポジトリの名前は「howahowablog/Pos」として「Private」で作成しています。
この記事での接続状態です。
次に、git branchコマンドを実行します。「mainブランチ」が選択されていない場合は、git checkout mainコマンドを入力します。
ここまで終えたら次の2つのコマンドを入力します。
git fetch originコマンド
git merge –allow-unrelated-histories origin/mainコマンド
上のコマンドについては次の記事を参考にしてください。
https://howahowablog.com/synchronizing-remote-repositories/git commit コマンドを利用してコミットします。
git commit -m “django pos commit”コマンドを入力
git push origin mainコマンドでリモートリポジトリへプッシュします。
無事にpushが完了しました。
サーバー側(本番環境側)での作業
サーバー側での必要な作業は次の通りです。
- Virtual BoxにRocky Linux を準備する
- DBMS(この記事ではPostgreSQL)のインストールと設定
- gitのインストールと設定
- Githubからプロジェクトをクローンする
- python仮想環境の準備
- gunicornのインストールと設定
- Webサーバー(この記事ではnginx)のインストールと設定
Rocky Linuxの準備
VirtualBoxに、Rocky Linux 9 を準備します。この記事では「Minimal」のイメージをインストールして、Cockpitを有効化しています。また、一般ユーザーで「django」ユーザーを作成しています。
VirtualBoxのインストール方法はこちら
Rocky Linux 9のインストール方法はこちら(今回の記事ではソフトウェアの設定は標準ツールのみ選択し、ストレージ設定は自動生成で完了をしています。)
Cockpitの有効化についてはこちら
サーバ側に必要なソフトウェアは次の5つです。
- データベース(この記事ではPostgreSQL)
- git
- pythonとpython仮想環境(Rocky Linux では標準でインストールされています。)
- gunicorn
- Webサーバー(この記事ではnginx)
ソフトウェアインストール前の準備
ルートユーザーに切り替えます。
[django@localhost ~]$ su –
Password:
dnfのパッケージリストを格納したデータベースを事前に保存します。
[root@localhost ~]# dnf makecache
全てのパッケージをアップデートします。
[root@localhost ~]# dnf update -y
Linuxを再起動します。
[root@localhost ~]# reboot
再起動後、再度サインインしてルートユーザーに切り替えます。
PostgreSQLの準備
データベースのインストール
PostgreSQLのインストールは次のリファレンスを参考にして行います。
今回のRocky Linux 9が標準で利用するPostgreSQLのバージョンを確認する場合は次のコマンドを入力します。
[root@localhost ~]# dnf info postgresql-server
違うバージョンを利用する場合はリファレンスに従ってください。
PostgreSQL サーバーパッケージをインストールします。
[root@localhost ~]# dnf install postgresql-server
Is this okと聞かれるので「y」と入力します。
Is this ok [y/N]: y
インストールが完了します。
データベースの設定
PostgreSQLの設定は次のリファレンスを参考にして行います。
データベースクラスターを初期化します。
[root@localhost ~]# postgresql-setup –initdb
設定ファイルの編集を行います。
[root@localhost ~]# vi /var/lib/pgsql/data/postgresql.conf
viエディタのコマンドモードで「/password」として「#password_encryption = md5」の行を検索します。
検索後「Enterキー」を押下して、「i」を押下します(インサートモードに切り替えます)。該当箇所を次のように編集します。
password_encryption = scram-sha-256
コマンドモードに切り替えて保存します。(「:wq」で上書き保存し終了します。)
続けて「pg_hba.conf」の設定を行います。
[root@localhost ~]# vi /var/lib/pgsql/data/pg_hba.conf
IPv4 local connections:の最後の部分(一番右側の設定)を
「ident」から「scram-sha-256」に変更します。
コマンドモードに切り替えて保存します。(「:wq」で上書き保存し終了します。)
postgresql サービスを起動します。
[root@localhost ~]# systemctl start postgresql.service
エラーが表示されなければ起動しています。
systemctl status postgresql.serviceで稼働しているかの確認もできます。
postgres という名前のシステムユーザーとしてログインします。(postgres はPostgreSQLをインストールした時から準備されているユーザーです。)
[root@localhost ~]# su – postgres
プロンプトが切り替わります。
[postgres@localhost ~]$
PostgreSQL インタラクティブターミナルを起動します。
[postgres@localhost ~]$ psql
psql (13.11)
Type “help” for help.
Postgreのインタラクティブターミナルが起動しプロンプトが次のようになります。
postgres=#
現在のデータベース接続に関する情報を取得するには次のように入力します。
プロンプト上では「¥」はバックスラッシュで表示されます。
postgres=# \conninfo
djangoで利用する「ユーザー」と「パスワード」を作成します。下のSQL文の赤文字部分がそれぞれ「ユーザー」と「パスワード」になります。
文法
postgres=# CREATE USER mydbuser WITH PASSWORD ‘mypasswd’;
この記事では「ユーザー」をdjangouser、「パスワード」を ‘password’として設定します。本来であればパスワードは推測されにくいもので作ります。
postgres=# CREATE USER djangouser WITH PASSWORD ‘password’;
djangodatabase という名前のデータベースを作成します。
postgres=# CREATE DATABASE djangodatabase;
djangouserへ権限を付与します。
postgres=# GRANT ALL PRIVILEGES ON DATABASE djangodatabase TO djangouser;
\q メタコマンドを使用して、インタラクティブターミナルからログアウトします。
postgres-# \q
postgres ユーザーセッションからログアウトします。
[postgres@localhost ~]$ logout
djangouserとして PostgreSQL ターミナルにログインし、ホスト名を指定して、初期化中に作成されたデフォルトの postgres データベースに接続します。
PostgreSQLを再起動します。
[root@localhost ~]# systemctl restart postgresql.service
新しく作成したユーザーでログインします。
[root@localhost ~]# psql -U djangouser -h 127.0.0.1 -d djangodatabase
パスワードを入力します。
Password for user djangouser:password
psql (13.11)
Type “help” for help.
プロンプトが変わります。
djangodatabase =>
タイムゾーンをDjangoと合わせます。
djangodatabase => ALTER ROLE djangouser SET timezone TO ‘UTC’;
\q メタコマンドを使用して、インタラクティブターミナルからログアウトして、Rocky Linux 9 のルートユーザーに戻ります。
djangodatabase => \q
プロンプトが切り替わります。
[root@localhost ~]#
Postgreデータベースの設定は以上です。
データベースに関わる「settings.py」の編集
viエディタで「settings.py」(この記事では「settingsフォルダの中のsettings_product.pyファイル」)を開き、「DATABASES」部分を次のように編集します。
from .base import *
# SECURITY WARNING: keep the secret key used in production secret!
# 何も入力しません。
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
#この部分には本番環境でのIPアドレスを入れます。現在は「*」としています。
ALLOWED_HOSTS = [" * "]
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djangodatabase', # データベース名
'USER': 'djangouser', # ユーザー名
'PASSWORD': 'password', # パスワード
'HOST': '"127.0.0.1', # ループバックアドレス
'PORT': '5432', # ポート番号:5432
}
}
設定は以上です。
gitの準備
gitのインストールと設定
Rocky Linux 9 へのGitのインストールについてはこちらを参考にして行います。但し、インストール時のコマンドは「yum」ではなく「dnf」を利用しています。
ルートユーザーに切り替えます。
[django@localhost ~]$ su –
Password:
[root@localhost ~]# dnf install git
インストールが始まります。
途中で「Is this ok」と聞かれるので「y」と入力します。
Total download size: 14 M
Installed size: 61 M
Is this ok [y/N]:y
インストールが完了します。
デフォルトのテキストエディターの設定(この記事ではviとしています。)
[root@localhost ~]# git config –global core.editor vi
ユーザー情報の登録(下は例です。実際の情報に置き換えて入力します。この記事でもユーザー名とメールアドレスは個人のもので入力しています。)
[root@localhost ~]# git config –global user.name “John Doe“
[root@localhost ~]# git config –global user.email “john@example.com“
サーバー上にリモートリポジトリのクローン先ディレクトリを作成します。作成先はRocky Linux のインストール時に作成した「djangoユーザー」のhome/djangoディレクトリの直下にしています。名前は「pos」で作成しています。
[root@localhost ~]# exit
logout
[django@localhost ~]$ mkdir pos
posディレクトリに移動します。
[django@localhost ~]$ cd pos
プロンプトが切り替わります。
[django@localhost pos]$
接続用の鍵を生成します。
[django@localhost pos]$ ssh-keygen -t ed25519 -C “john@example.com“
Generating public/private ed25519 key pair.
次は何も入力せずにEnterキーを押下します。
Enter file in which to save the key (/home/django/.ssh/id_ed25519):
パスフレーズを入力します。忘れないようにします。
Created directory ‘/home/django/.ssh’.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
生成した鍵はユーザーディレクトリ内の隠しディレクトリ「.ssh」に保存されています。次のコマンドで鍵が存在しているかを確認します。
[django@localhost pos]$ ls -al ~/.ssh
次のコマンドで鍵を表示してコピーします。(CockpitでLinux操作を行っている場合はコピーしたいプロンプト上の文字部分を選択して右クリックで簡単にコピーができます。(鍵の追加方法については次の記事を参考にしてください。)
https://howahowablog.com/connect-to-github-using-ssh/catコマンドで表示した鍵をマウスで選択して右クリック「Copy」します。
[django@localhost pos]$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AA************************************john@example.com
コピーした鍵をGithubに登録します。
Githubへの接続ができるか確認します。ホームディレクトリから次のコマンドを入力します。
[django@localhost ~]$ ssh -T git@github.com
接続していいかを問われるので「yes」と入力します。
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
パスフレーズを聞かれます。
Enter passphrase for key ‘/home/django/.ssh/id_ed25519’:(パスフレーズを入力)
パスフレーズを入力して次のように表示されればSSH接続の設定が正しく行えたことになります。
Hi howahowablog! You’ve successfully authenticated, but GitHub does not provide shell access.
作成したposディレクトリをgitの配下に置きます。
[django@localhost ~]$ cd pos
[django@localhost pos]$ git init
hint: Using ‘master’ as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config –global init.defaultBranch
hint:
hint: Names commonly chosen instead of ‘master’ are ‘main’, ‘trunk’ and
hint: ‘development’. The just-created branch can be renamed via this command:
hint:
hint: git branch -m
Initialized empty Git repository in /home/django/pos/.git/
[django@localhost pos]$ ls -la
total 0
drwxr-xr-x. 3 django django 18 Oct 14 02:49 .
drwx——. 4 django django 127 Oct 14 02:07 ..
drwxr-xr-x. 7 django django 119 Oct 14 02:49 .git
.gitディレクトリが作成されたのが確認できます。
次のコマンドで利用したいリモートリポジトリを登録します。
git remote add <URLの別名><接続先のリモートリポジトリのURL>コマンド
[django@localhost pos]$ git remote add origin リモートリポジトリのURL
次のコマンドでリモートリポジトリのプロジェクトをサーバーにクローンします。
[django@localhost pos]$ git clone リモートリポジトリのURL
Cloning into ‘Pos’…
Enter passphrase for key ‘/home/django/.ssh/id_ed25519’:(パスフレーズを入力)
remote: Enumerating objects: 216, done.
remote: Counting objects: 100% (216/216), done.
remote: Compressing objects: 100% (103/103), done.
remote: Total 216 (delta 87), reused 212 (delta 86), pack-reused 0
Receiving objects: 100% (216/216), 87.20 KiB | 273.00 KiB/s, done.
Resolving deltas: 100% (87/87), done.
以上でRocky Linux 9内にローカルで開発したDjangoのプロジェクトを呼び込むことができました。
python仮想環境の準備
Rocky Linux上でpython仮想環境を作成
Rocky Linux 9 にはすでにpython3.9がインストールされているので、これを利用してpython仮想環境を作成します。
次のコマンドでGithubからクローンしたPosプロジェクトが確認できます。このプロジェクトディレクトリをカレントディレクトリとして仮想環境を作成します。
[django@localhost pos]$ ls
Pos
Posプロジェクトへ移動します。
[django@localhost pos]$ cd Pos
中身を確認します。main.pyがあることを確認します。
[django@localhost Pos]$ ls
README.md main.py pos requirements.txt
pythonがインストールされているか、どのバージョンか、複数存在するかなどを念のため確認します。
[django@localhost Pos]$ python -V
Python 3.9.16
venvを利用してpython仮想環境「env(名前はenvでなくても構いません)」を作成します。
[django@localhost Pos]$ python3 -m venv env
中身を確認します。
[django@localhost Pos]$ ls
envが確認できます。
README.md env main.py pos requirements.txt
python仮想環境を立ち上げます。
[django@localhost Pos]$ source env/bin/activate
プロンプトが変わりpython仮想環境が立ち上がったのが確認できます。
(env) [django@localhost Pos]$
インストールされているパッケージを出力(メモするため)できる「freeze」をpipを利用してインストールします。(今後、本番環境内でいろいろなパッケージをインストールするため、そのメモをとるのにfreezeが必要になります。)
(env) [django@localhost Pos]$ pip freeze
ひとまず、Githubからクローンしたプロジェクトにあるrequirements.txtを利用して必要なパッケージをインストールします。これで開発環境側で利用していたパッケージと同じパッケージを同じバージョンで全てインストールできます。
(env) [django@localhost Pos]$ pip install -r requirements.txt
インストール後に次の表示が出た場合はpipをアップグレードしておきます。
(env) [django@localhost Pos]$ python3 -m pip install –upgrade pip
シークレットキーの生成と設定
続けて、本番環境用のシークレットキーを生成して「settings_product.py」に登録します。
manage.pyのあるディレクトリに移動してインタラクティブシェルを起動します。
(env) [django@localhost Pos]$ cd pos
(env) [django@localhost pos]$ python manage.py shell
Python 3.9.16 (main, Sep 12 2023, 00:00:00)
[GCC 11.3.1 20221121 (Red Hat 11.3.1-4)] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
(InteractiveConsole)
シークレットキーの再生成をします。
>>> from django.core.management.utils import get_random_secret_key
>>>get_random_secret_key()
鍵が生成されるのでクリップボードにコピーします。(Cockpitのターミナルだと右クリックでコピーができます。)
‘xv!*********************************************7@f)’
次のコマンドでpython仮想環境に戻ります。
>>> exit()
python仮想環境に戻ったら、viエディタを利用して「settingsディレクトリ」内の「settings_product.pyファイル」にある「SECRET_KEY」部分に貼り付けます。
from .base import *
# SECURITY WARNING: keep the secret key used in production secret!
# 新しいシークレットキーを設定します。
SECRET_KEY = 'xv!*********************************************7@f)'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
#この部分には本番環境でのIPアドレスを入れます。現在は「*」としています。
ALLOWED_HOSTS = [" * "]
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djangodatabase', # データベース名
'USER': 'djangouser', # ユーザー名
'PASSWORD': 'password', # パスワード
'HOST': '"127.0.0.1', # ループバックアドレス
'PORT': '5432', # ポート番号:5432
}
}
pythonからPostgreSQLに接続するためのモジュールのインストール
python仮想環境が作成とシークレットキーの設定ができたので、ここで初めて、pythonからPostgreSQLに接続するためのモジュールをpipを利用してインストールします。(この記事ではビルド済みの「psycopg2-binary」をインストールします。)
(env) [django@localhost Pos]$ pip install psycopg2-binary
python仮想環境を終了します。
(env) [django@localhost pos]$ deactivate
ルートユーザーに切り替えてPostgreSQLの稼働状況を確認します。
[django@localhost pos]$ su –
Password:
[root@localhost ~]# service postgresql status
以下のように表示された場合は、起動する必要があります。
Redirecting to /bin/systemctl status postgresql.service
○ postgresql.service – PostgreSQL database server
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; preset: disabled)
Active: inactive (dead)
PostgreSQLを起動します。
[root@localhost ~]# systemctl start postgresql.service
ルートユーザーを抜けて再度、python仮想環境を起動します。
[root@localhost ~]# exit
logout
python仮想環境「env」を持っているディレクトリに移動します。
(この記事では「Pos」ディレクトリです。)
[django@localhost pos]$ cd ../
python仮想環境を起動します。
[django@localhost Pos]$ source env/bin/activate
「manage.py」があるディレクトリに移動します。(この記事では「Posプロジェクト」直下の「posディレクトリ」となります。)
(env) [django@localhost Pos]$ cd pos
データベースのアクセスをチェックします。
(env) [django@localhost pos]$ python manage.py check –database default
System check identified no issues (0 silenced).
マイグレーションします。
(env) [django@localhost pos]$ python manage.py makemigrations
No changes detected
(env) [django@localhost pos]$ python manage.py migrate
Djangoアプリケーションのスーパーユーザーを作成します。
(env) [django@localhost pos]$ python manage.py createsuperuser
ユーザー名 (leave blank to use ‘django’): admin
メールアドレス:
Password: ←パスワードを入力
Password (again): ←確認としてパスワードを再度入力
このパスワードは ユーザー名 と似すぎています。
このパスワードは短すぎます。最低 8 文字以上必要です。
このパスワードは一般的すぎます。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
(env) [django@localhost pos]$
ここまでで、DjangoとPostgreSQLの連携の設定が終了しました。
Gunicornの準備
Gunicornのインストールと設定①
Djangoの実行にはGunicornというソフトウェアが必要です。これは「PythonのWeb Server Gateway Interface(WSGI)を実装するHTTPサーバー」です。DjangoアプリケーションとWebサーバー間のインターフェースとして機能してくれます。
python仮想環境(この記事ではenv)を持つディレクトリ(この記事ではPosディレクトリ)に移動してGunicornをインストールします。
(env) [django@localhost Pos]$ pip install gunicorn
インストール後、Gunicornを利用してDjangoアプリケーションが実行できるかを確認します。そのために一時的に任意のポート(この記事では8000番)のファイアウォールを開放します。
ルートユーザーに切り替え次のコマンドを入力します。(一般ユーザーからsudoを付けて実行も可能です。)
(env) [django@localhost pos]$ deactivate
[django@localhost pos]$ su –
Password:
[root@localhost ~]# firewall-cmd –add-port=8000/tcp –permanent
success
[root@localhost ~]# firewall-cmd –reload
success
ルートユーザーを抜けてpython仮想環境に戻ります。
[django@localhost Pos]$ source env/bin/activate
(env) [django@localhost Pos]$ cd pos
viエディタで「settings_product.py」を開いて「ALLOWED_HOSTS」に本番環境で利用するIPアドレスを入力します。IPアドレスは「ifconfig」コマンドで確認します。この記事作成時の筆者の環境では「192.168.2.155」でした。(固定IPアドレスにするのが望ましいですが、デプロイの流れを確認する記事なので固定IPアドレスの設定は行っていません。)
from .base import *
# SECURITY WARNING: keep the secret key used in production secret!
# 新しいシークレットキーを設定します。
SECRET_KEY = 'xv!*********************************************7@f)'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
# 環境によって変更
ALLOWED_HOSTS = ["192.168.2.155 "]
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djangodatabase', # データベース名
'USER': 'djangouser', # ユーザー名
'PASSWORD': 'password', # パスワード
'HOST': '127.0.0.1', # localhost
'PORT': '5432', # 5432
}
}
settingsフォルダ内のbase.pyに次の4行を追記します。
(「base.py」は「元settings.py」)
import os
STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)
MEDIA_URL = ‘/media/’
MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’)
from pathlib import Path
# ここがひとつ目#######################
import os
BASE_DIR = Path(__file__).resolve().parent.parent.parent
INSTALLED_APPS = [
'monthlyaccount.apps.MonthlyaccountConfig',
'depositbook.apps.DepositbookConfig',
'cashbook.apps.CashbookConfig',
'accountlist.apps.AccountlistConfig',
'consumptiontax.apps.ConsumptiontaxConfig',
'dailyaccount.apps.DailyaccountConfig',
'bills.apps.BillsConfig',
'customerlist.apps.CustomerlistConfig',
'menulist.apps.MenulistConfig',
'mainpage.apps.MainpageConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'pos.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
WSGI_APPLICATION = 'pos.wsgi.application'
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_TZ = True
STATIC_URL = '/static/'
# ここがふたつ目#######################
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# ここがみっつ目#######################
MEDIA_URL = '/media/'
# ここがよっつ目#######################
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ここまで入力ができると、WSGIサーバーからのレスポンスを確認できます。次のように入力してALLOWED_HOSTSに指定しているアドレスにファイアウォールで許可したポートを付加してブラウザでアクセスします。
起動します。
(env) [django@localhost pos]$ gunicorn –bind 0.0.0.0:8000 pos.wsgi:application
この記事の場合は「192.168.2.155:8000」でアクセスします。
ブラウザで次のように表示されました。
今はまだCSSが適用されていませんが、nginxをインストールして設定するときに設定を編集します。その事前準備としてプロジェクト内の静的ファイルを収集します。これは、先ほどbase.pyに追記した「STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)」と「MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’)」によって収集する箇所を指定しています。
(env) [django@localhost pos]$ python manage.py collectstatic
150 static files copied to ‘/home/django/pos/Pos/static’.
staticフォルダを確認できます。
(env) [django@localhost Pos]$ ls
README.md env main.py pos requirements.txt static
(env) [django@localhost Pos]$ ls static/
accountlist bills consumptiontax dailyaccount mainpage monthlyaccount
admin cashbook customerlist depositbook menulist
開いたファイアウォールを閉じておきます。
(env) [django@localhost pos]$ deactivate
[django@localhost pos]$ su –
Password:
[root@localhost ~]# firewall-cmd –remove-port=8000/tcp –permanent
success
[root@localhost ~]# firewall-cmd –reload
success
Webサーバー(nginx)の準備
Webサーバーソフトのインストールとファイアウォールの設定
Webサーバーの「nginx」をインストールします。
[root@localhost ~]# dnf install nginx
Total download size: 640 k
Installed size: 1.8 M
Is this ok [y/N]: y
Rocky Linux を起動したときにnginxも自動で起動するように設定します。
[root@localhost ~]# systemctl enable nginx
nginxを起動します。
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# systemctl status nginx
ファイアウォールの設定から80番ポートを開きます。
[root@localhost ~]# firewall-cmd –add-service=http –permanent
success
[root@localhost ~]# firewall-cmd –reload
success
Gunicornの設定②
gunicorn設定ファイル(「gunicorn.socket」と「gunicorn.service」)の作成と設定を行います。Rocky Linux で設定ファイルは/etc/systemd/systemディレクトリに作成します。
[root@localhost ~]# vi /etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
[root@localhost ~]# vi /etc/systemd/system/gunicorn.service
(注意)ExecStartの箇所でフォルダの移動を指定しています。必須ではありませんが、この記事の場合「pos.wsgi:application」の場所が深いため、移動の設定が必要になります。
–chdir /home/django/pos/Pos/pos
次の部分はwsgiの準備されているディレクトリを指定して、
「ディレクトリ名.wsgi:application」と記述します。
今回の記述例: pos.wsgi:application
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=django
Group=django
WorkingDirectory=/home/django/pos/Pos/pos/pos
ExecStart=/home/django/pos/Pos/env/bin/gunicorn --workers 3 --bind unix:/run/gunicorn.sock --chdir /home/django/pos/Pos/pos pos.wsgi:application
[Install]
WantedBy=multi-user.target
新規作成した設定ファイルが読み込まれるようにreloadします。
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start gunicorn.socket
[root@localhost ~]# systemctl enable gunicorn.socket
Created symlink /etc/systemd/system/sockets.target.wants/gunicorn.socket → /etc/systemd/system/gunicorn.socket.
[root@localhost ~]# systemctl status gunicorn.socket
Webサーバーの設定
Gunicornの設定ファイルが作成できたので、最後にWebサーバー(この記事ではnginx)の設定を行います。
設定ファイル(nginx.conf)を開いて次の一行を追記します。これはサーバーの名前が長すぎるときにエラーを吐き出さないようにするために追記します。
[root@localhost ~]# vi /etc/nginx/nginx.conf
http {}の中にserver_names_hash_bucket_size 64;
続けて「nginx.conf」に呼び込まれるオリジナルの設定ファイルを作成します。
「nginx.conf」にはinclude /etc/nginx/conf.d/*.conf;という記述があり、「/etc/nginx/conf.dディレクトリ」内に作成した〇〇.confというファイルを読み込めるように仕組まれています。
この記事では「djangoapp.conf」という名前で作成しています。
[root@localhost ~]# vi /etc/nginx/conf.d/djangoapp.conf
server {
listen 80 default_server;
server_name 192.168.2.155;
location /static/ {
root /home/django/pos/Pos;
}
location /media/ {
root /home/django/pos/Pos;
}
location / {
# gunicorn.socketを作成するとRocky Linux のrunディレクトリにgunicorn.sockというファイルが自動で生成されます。
proxy_pass http://unix:/run/gunicorn.sock;
# ホスト名が呼ばれます。
proxy_set_header Host $http_host;
# 送信元のアドレスが呼ばれます。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
設定ファイルのテストを行います。
[root@localhost ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
何かしらの間違いがある場合は設定ファイルの行数を出力してくれます。(下の例では「gunicorn.socket」の14行目にミスがあります。)
Gunicornの設定ファイルの再読み込みとnginxの再起動を行います。
[root@localhost ~]# systemctl restart gunicorn.socket
[root@localhost ~]# systemctl restart gunicorn.service
[root@localhost ~]# systemctl reload nginx.service
上の3つのコマンドを入力するときにエラーが出た場合は次のコマンドを入力してから打ち直します。
[root@localhost ~]# systemctl daemon-reload
SELinuxの設定を変更します。
[root@localhost ~]# vi /etc/selinux/config
Rocky Linux を再起動して、忘れずにPostgreSQLも起動します。
[root@localhost ~]# reboot
[django@localhost ~]$ su –
Password:
[root@localhost ~]# systemctl start postgresql.service
[root@localhost ~]#
指定したIPアドレスへアクセスします。(今回は192.168.2.155)
PCでの表示
スマートフォンでの表示はうまくいっていません。Rocky Linux のhome/djangoディレクトリに、その他のユーザーの実行権限を付与します。
ホームディレクトリのその他のユーザーへの実行権限の付与
[root@localhost ~]# ls
anaconda-ks.cfg
[root@localhost ~]# cd ../
[root@localhost /]# ls
afs boot etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var
[root@localhost /]# cd home
[root@localhost home]# ls -l
total 4
drwx—––. 5 django django 4096 Oct 15 13:52 django
[root@localhost home]# chmod 701 django/
[root@localhost home]# ls -l
total 4
drwx—–x. 5 django django 4096 Oct 15 13:52 django
[root@localhost home]#
スマートフォンで再度アクセスします。今度はCSSが適用されています。
その他、このような表示になった場合は
502 Bad Gatewayが表示されたら「gunicorn.socket」や「gunicorn.service」の設定ミスが疑えます。その他にもnginxの新規に作成した.confも確認します。
その他にも、うまくいかない場合に次の権限付与も検討します。
「manage.py」に755の権限を付与します。
[root@localhost pos]# chmod 755 manage.py
Djangoのデプロイ作業については以上となります。
ブックマークのすすめ
「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。
os.environを利用して環境変数からの取り出しもできますが、今回は直接貼り付けています。