概要
PostgreSQLの初期設定、Djangoのデータベース接続、settings.pyの本番向け設定、起動確認までを整理する。
Djangoサイトを公開する最後の段階では、データベース、マイグレーション、セキュリティ設定、静的ファイル、Apache連携をまとめて確認する必要がある。runserverと本番起動の違いも押さえておく。
この記事の構成
- 対象環境と利用上の注意
本文記載時の環境と現在そのまま利用できない箇所を確認。 - 前提環境
手順で使用するOS、ソフトウェア、構成などの前提条件を確認。 - 作業時の注意点
設定変更やコマンド実行前に確認しておきたい注意点を整理。 - データベースの環境構築
データベースの環境構築の手順と確認ポイントを整理。 - Django周りの設定
Django周りの設定の手順と確認ポイントを整理。 - PostgreSQL周りの設定
PostgreSQL周りの設定の手順と確認ポイントを整理。 - settings.pyの設定
settings.pyの設定の手順と確認ポイントを整理。 - 起動確認
起動について、確認する項目と結果の見方を整理。
対象環境と利用上の注意
- 本文記載時の環境
2018年当時のCentOS 7.4環境の記録をもとに、Django 2.2、PostgreSQL 9.6、psycopg2 2.8系と整合するよう再構成した例。
データベースはDjangoと同じVPSで動かす構成を前提とする。 - 確認時期
2026年8月にDjango、PostgreSQL、psycopgの公式資料と照合。
現在の環境でデータベース作成からApache経由の起動まで一連の手順は再実行していない。 - 現在そのまま利用できない箇所
CentOS 7、Django 2.2、PostgreSQL 9.6、psycopg2 2.8系は旧環境である。
PGDGのパッケージ名、認証方式、Djangoの設定要件も変わるため、新規構築ではサポート中の組合せと現行の公式手順を利用する。
前提環境
- OS
CentOS 7.4(サポート終了済み) - 言語
Python - Webサーバー
Apache - フレームワーク
Django - データベース
PostgreSQL 9.6(サポート終了済み) - ドメイン
example.com
作業時の注意点
- データベースユーザー
作成したユーザー名とDjangoのDATABASES設定を一致させる。 - DEBUG設定
本番ではFalseにし、ALLOWED_HOSTSを正しく設定。 - マイグレーション
モデル変更後はmakemigrationsとmigrateを忘れない。 - runserverとApache
両方を混同すると、どちらで動いているか分かりにくくなる。
実施内容
データベースの環境構築
-
PostgreSQL 9.6インストール(旧環境の例)
当時のPostgreSQL公式Yumリポジトリ(PGDG 9.6)を有効化した後、Django 2.2の要件を満たすPostgreSQL 9.6を導入。
現在はPostgreSQL 9.6もサポート終了済みなので、このパッケージ名を新規構築へ流用せず、サポート中のOSとPostgreSQLを選ぶ。$ yum -y install postgresql96-server postgresql96-devel gcc -
DjangoからPostgreSQLへ接続するドライバーをインストール
この記事のPython 3.6環境では、対応するpsycopg2を仮想環境へ導入。新しい環境では、利用中のDjangoが対応するpsycopgまたはpsycopg2と公式の導入方法を確認。$ source /var/www/vops/bin/activate $ export PATH="/usr/pgsql-9.6/bin:$PATH" $ python -m pip install "psycopg2<2.9" -
データベースとユーザーの作成
データベースexampledbとアクセスユーザーappuserを作成。
PostgreSQLでは引用符なしの識別子が小文字へ変換されるため、SQLとDjangoの設定で最初から小文字に統一する。$ /usr/pgsql-9.6/bin/postgresql96-setup initdb # データベースの初期化 $ systemctl start postgresql-9.6 # PostgreSQLを起動 $ systemctl enable postgresql-9.6 # 自動起動を有効化 $ sudo -u postgres /usr/pgsql-9.6/bin/psql # postgresでログイン postgres=# CREATE USER appuser WITH PASSWORD '十分に長いパスワード'; postgres=# CREATE DATABASE exampledb OWNER appuser; postgres=# ALTER ROLE appuser SET client_encoding TO 'utf8'; postgres=# ALTER ROLE appuser SET default_transaction_isolation TO 'read committed'; postgres=# ALTER ROLE appuser SET timezone TO 'Asia/Tokyo'; -
PostgreSQLを起動確認
active (running) と表示されていれば成功。$ systemctl status postgresql-9.6
Django周りの設定
以下、Djangoのモデル定義が終わっていることが前提。
-
マイグレーションファイルを作成
※ マイグレーションファイル(モデルの内容をデータベースに適用するファイル)$ /var/www/vops/bin/python /var/www/vops/ops/manage.py makemigrations -
マイグレーションファイルをデータベースに反映
マイグレーションファイルを基に、データベースの構造(テーブルの作成や更新)を変更。$ /var/www/vops/bin/python /var/www/vops/ops/manage.py migrate -
スーパーユーザーの作成
$ /var/www/vops/bin/python /var/www/vops/ops/manage.py createsuperuser -
Djangoの開発用サーバーを外部公開しない
runserverは動作確認専用であり、本番公開を目的としたサーバーではない。
同じVPS内から127.0.0.1で確認し、8080番ポートをfirewalldで外部へ開放しない。
PostgreSQL周りの設定
-
postgresql.confの
listen_addressesをローカル接続に限定
DjangoとPostgreSQLが同じVPS上にあるため、インターネットから5432番ポートへ接続させる必要はない。$ vim /var/lib/pgsql/9.6/data/postgresql.conf listen_addresses = 'localhost' -
pg_hba.conf(認証設定ファイル)にドメイン情報を追加
ローカルホストからexampledbへ接続するルールを追加。
アドレス欄はサーバー自身ではなく、接続元クライアントの範囲を表す。pg_hba.confは上から順に最初に一致したルールが使われるため、host all all 127.0.0.1/32 ...のような広いルールより前へ挿入する。$ vim /var/lib/pgsql/9.6/data/pg_hba.conf # ローカルホスト向けの広いhostルールより前へ追加 host exampledb appuser 127.0.0.1/32 md5md5はこの旧環境に合わせた認証方式である。現行PostgreSQLではSCRAM認証を優先し、サーバーとクライアントの対応状況を公式ドキュメントで確認。 -
PostgreSQLの再起動
listen_addressesとpg_hba.confを変更した後、PostgreSQLを再起動。
5432番ポートはfirewalldで公開しない。データベースを別サーバーへ分離する場合だけ、接続元IP、TLS、クラウド側のセキュリティグループを含めて別途設計。$ systemctl restart postgresql-9.6
settings.pyの設定
- デバッグモードの無効化
DEBUG = False # 開発モードのTrueからFalseに修正 - ALLOWED_HOSTSを自身のドメインに設定
ALLOWED_HOSTS = ['example.com'] # 自身のドメインに修正 - INSTALLED_APPSにアプリケーション名を追加
INSTALLED_APPS = [ 'webapp', # アプリケーション名を追加 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] - SSL/TLS周りの設定を追加
SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = TrueSECURE_PROXY_SSL_HEADERは、TLSを終端する信頼済みリバースプロキシがX-Forwarded-Protoを設定し、外部から届いた同名ヘッダーを除去できる場合にだけ設定。
ApacheのHTTPS VirtualHostからmod_wsgiへ直接渡す今回の構成では不要となる。 - ROOT_URLCONFの修正
ROOT_URLCONF = 'ops.urls' # URLとビューを対応付けるURLconfモジュールを指定 - DATABASESの設定
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'exampledb', 'USER': 'appuser', 'PASSWORD': os.environ['DJANGO_DB_PASSWORD'], 'HOST': '127.0.0.1', 'PORT': '5432' } }パスワードや
SECRET_KEYはソースコードへ直接書かず、環境変数や権限を制限した設定ファイルから読み込む。
この例ではDJANGO_DB_PASSWORDが未設定だとDjango起動時にエラーになるため、manage.pyを実行するシェルだけでなく、Apacheサービスの起動環境にも同じ値を安全に渡す必要がある。
具体的な受渡し方法はOSやサービス管理方法に合わせ、権限を制限した環境ファイルやシークレット管理機能を利用。 - 日本語化、タイムゾーンの設定
LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo' USE_I18N = True USE_L10N = 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')MEDIA_ROOTはアップロードファイルの保存先を定めるだけで、DEBUG=Falseの環境でApacheから自動配信されるわけではない。
メディア機能を使う場合は、アップロードされた内容を実行させない安全なApache設定またはオブジェクトストレージを別途用意する。STATIC_ROOTを設定した後、Apacheが配信する静的ファイルを集約。$ /var/www/vops/bin/python /var/www/vops/ops/manage.py collectstatic --noinput - ログの設定(任意)
まずは標準エラーへ出力するStreamHandlerを使うと、Apache側のエラーログやサービス管理機能へ集約しやすい。FileHandlerを使う場合は、mod_wsgiの実行ユーザーが出力先へ書き込める権限とSELinux設定を別途用意する。LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'all': { 'format': ' *** '.join([ "[%(levelname)s]", "asctime:%(asctime)s", "module:%(module)s", "message:%(message)s", "process:%(process)d", "thread:%(thread)d", ]) }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'all' }, }, 'loggers': { 'django': { 'handlers': ['console'], 'level': 'INFO', 'propagate': False, }, }, }
起動確認
-
Django単体の診断
manage.pyのrunserverをループバックアドレスだけにバインドし、VPS内から確認。
これは問題の切り分け用であり、本番トラフィックには使用しない。
上記のSECURE_SSL_REDIRECT=Trueが有効なため、このHTTPリクエストではHTTPSへのリダイレクトが返ればDjangoが応答していることを確認できる。
画面内容まで確認する場合は、本番設定を弱めず、リダイレクトを無効にした開発用設定を別途使用。$ /var/www/vops/bin/python /var/www/vops/ops/manage.py runserver 127.0.0.1:8080 $ curl -I -H 'Host: example.com' http://127.0.0.1:8080/ -
本番環境の起動確認
DjangoのデプロイチェックとApacheの構文確認を行い、Apache、PostgreSQLを再起動。
その後、https://example.comへアクセスし、作成したアプリがApache経由で表示されれば成功となる。$ /var/www/vops/bin/python /var/www/vops/ops/manage.py check --deploy $ apachectl configtest $ systemctl restart postgresql-9.6 httpd $ curl -I https://example.com/モデルを修正した場合は、manage.pyの
makemigrations、migrateを実行。runserverとApacheは通常は別ポートで動くため競合するわけではないが、確認先を取り違えないよう、単体診断後はrunserverを停止してApache経由の結果を確認。
まとめ
- Djangoサイト公開の仕上げでは、PostgreSQL、マイグレーション、settings.pyをまとめて確認。
- 本番環境ではDEBUGを無効化し、ALLOWED_HOSTSやSSL/TLS関連設定を整える。
- 起動確認はrunserverではなく、最終的にApache経由で確認。