DebianでpyenvとApacheとPostgreSQLを使ってDjangoを使うための手順

Django

はじめに

この記事では、Debianでpyenv + Apache2 + Djangoの環境を作ることを紹介します。
Pythonはpyenvを使って仮想環境を作ります。
仮想環境を作って運用すると長期に渡る保守性が向上するのでお勧めです。
今回は環境を作ってDjangoの管理画面にアクセスするまでを説明するのでDjangoのモデルは不要です。

環境

Apache2、PostgreSQLはDebianで提供されているバージョンを使います。
なお、Pythonはpyenvで提供されている最新バージョンを使います。

 - Debian bullseye 64bit
 - Apache 2.4.38
 - PostgreSQL 13
 - Python 3.9.7
 - Django 3.2.7

ディレクトリ構造は以下の通りです。

Apache2
 /etc/apache2/sites-available/000-default.conf

PostgreSQL
 /etc/postgresql/13/main/postgresql.conf

Django
 /home/www/wsgi/proj
   ┣ -- proj
        ┣ -- settings.py
        ┣ -- wsgi.py
   ┣ -- app
   ┣ -- templates
   ┣ -- static
   ┣ -- db.sqlite3

ApacheとPostgreSQLのインストール

ApacheとPostgreSQLは、Debianで提供されているパッケージをインストールします。

sudo apt install postgresql apache2

Pythonのインストール

pyenvを使って一般ユーザのホームディレクトリに作成します。
pyenvの環境変数をproflileに書き込むのですが書式が変わっています。
「2.Configure your shell’s environment for Pyenv」を参照してください。

GitHub - pyenv/pyenv: Simple Python version management
Simple Python version management. Contribute to pyenv/pyenv development by creating an account on Gi...

pyenvのインストールと設定

はじめにpyenvの環境を整備します。
/home/xxx/.profileの最終行に環境変数を追記します。
xxxは使用するユーザ名に置き換えてください。

cd /home/xxx
sudo apt install git
git clone https://github.com/pyenv/pyenv.git /home/xxx/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> /home/xxx/.profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> /home/xxx/.profile
echo 'eval "$(pyenv init --path)"' >> /home/xxx/.profile

/home/xxx/.profileの内容は以下のようになります。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

環境変数を反映させます。

. /home/xxx/.profile

または

source /home/xxx/.profile

pyenvをアップデートするためのモジュールをインストールします。

git clone git://github.com/yyuu/pyenv-update.git ~/.pyenv/plugins/pyenv-update

pyenvで新しいバージョンのPythonを扱うにはアップデートが必要です。

pyenv update

pipでモジュールをインストールするために必要なパッケージをインストールします。

sudo apt install -y gcc make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev apache2-dev

インストール可能なPythonのリスト表示して、最新バージョンをインストールします。
Apache2でmod_wsgiをモジュールとして使うので「–enable-shared」を指定します。
最後にインストールが成功したかを確認します。

pyenv install -l | grep '^  3\.[0-9]*\.[0-9]*'
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.9.7
pyenv versions

仮想環境を作成するためにpyenv-virtualenvをインストールします。

git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

仮想環境proj-397を作成後、確認します。

pyenv virtualenv 3.9.7 proj-397
pyenv versions

仮想環境proj-397に切り替えた後、pipをアップグレードします。

pyenv global proj-397
pip install --upgrade pip

Djangoをインストールします。

pip install Django

pyenv環境のPythonのパスは以下となります。

/home/xxx/.pyenv/shims/python

以下のコマンドでファイルに列挙したモジュールをインストールできますが、バージョン番号を消してモジュール名だけにした方がモジュール間の競合が起こりません。

pip install -r ~/requirements.txt

~/requirements.txtの中身(抜粋)は以下になります。

Django
django-extensions
django-formtools
django-import-export
django-uuidfield
・・・

Djangoの設定と動作確認

都合でApache2のDocumentRootは/home/www/htmlに変更するので、Djangoのプロジェクトも/home/www/wsgi以下に作成します。
また、自分のアカウント権限でプロジェクトを作成したいので、www-dataグループに自分のアカウントを追加します。
同時に/home/www以下のパーミッションをグループに所属するユーザが書き込みできるように775に設定します。

コマンドプロンプトを起動してDjangoのプロジェクト(proj)とアプリ(app)を作成します。
動作確認なのでデータベースはSQLite(以下、sqlite3)を使います。

sudo usermod -aG www-data 自分のアカウント
sudo mkdir -p /home/www/wsgi
sudo chown -R www-data.www-data /home/www
sudo chmod -R 775 /home/www
cd /home/www/wsgi
django-admin startproject proj
cd proj
python manage.py startapp app
python manage.py makemigrations
python manage.py migrate

Webブラウザでアクセスできるようにテキストエディタでsettings.pyを編集します。
パスの設定はPathモジュールを使います。

cd /home/www/wsgi/proj/proj
vi settings.py

アクセスの許可を与えます。
テストなので全て許可します。

ALLOWED_HOSTS = ['*']

テンプレートの場所を指定します。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [ BASE_DIR / 'templates'],  # Templateを一箇所にまとめる設定
        ・・・

言語やタイムゾーンを指定します。

USE_I18N      = True
USE_L10N      = True
TIME_ZONE     = 'Asia/Tokyo'
USE_TZ        = True
LANGUAGE_CODE = 'ja'

staticファイルの場所を指定します。

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static/'
]

接続テスト

Djangoに付属するサーバを起動します。

cd /home/www/wsgi/proj
python manage.py runserver 0:8000

WebブラウザからDjangoの管理画面にアクセスできれば成功です。

ローカルからアクセスする場合
 http://localhost:8000/admin

別のパソコンからアクセスする場合
Djangoで開発するパソコンのIPアドレスが192.168.10.3とする。
 http://192.168.10.3:8000/admin

Apache2の設定

Apache2を経由してDjangoのプロジェクトにアクセスするために設定を行います。
作成したpyenv環境に合わせて/etc/apache2/sites-available/000-default.confを編集します。
ローカルで使うのでhttpのポート80で設定しますが、httpsでも設定は同様です。
xxxはご使用のユーザ名、proj-397はpyenvの仮想環境名、3.9.7は仮想環境のPythonのバージョン番号に置換してください。
LoadModuleで使用するmod_wsgiはパスが正しいか確認してください。

<VirtualHost *:80>
    ServerAdmin aaa@bbb.cc.dd

    # 環境に合わせて変更します。
    DocumentRoot /home/www/html/
    <Directory />
        Options +FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory /home/www/html/>
        Options +Indexes +FollowSymLinks +MultiViews
        AllowOverride None
        Require all denied
        Require host .hoge.jp
        Require ip 192.168.10.8
    </Directory>

    # mod_wsgi
    LoadModule wsgi_module /home/xxx/.pyenv/versions/3.9.7/envs/proj-397/lib/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so
    <Files wsgi.py>
        Require all denied
        Require host .hoge.jp
        Require ip 192.168.10.8
    </Files>

    # Django admin
    Alias /static/admin /home/xxx/.pyenv/versions/3.9.7/envs/proj-397/lib/python3.9/site-packages/django/contrib/admin/static/admin
    <Directory /home/xxx/.pyenv/versions/3.9.7/envs/proj-397/lib/python3.9/site-packages/django/contrib/admin/static/admin>
        Require all denied
        Require host .hoge.jp
        Require ip 192.168.10.8
    </Directory>

    # Django Project
    Alias /static/ /home/www/wsgi/proj/static/
    WSGIScriptAlias /proj /home/www/wsgi/proj/proj/wsgi.py
    WSGIScriptReloading On
    # DjangoのDaemonを日本語環境にするために「WSGIDaemonProcess」で「lang=ja_JP.utf8」を指定しています。
    # processes、threadsの数は環境に合わせて変更します。
    # python-pathはDjangoのプロジェクトのディレクトリです。
    # python-homeはpyenvで作成した仮想環境のディレクトリです。
    # userはDebianでのApache2の実行ユーザ名です。
    # projはDjangoのプロジェクト名と同じにします。
    WSGIDaemonProcess proj user=www-data group=www-data processes=5 threads=25 maximum-requests=128 lang=ja_JP.utf8 python-path=/home/www/wsgi/proj python-home=/home/xxx/.pyenv/versions/proj-397 display-name=%{GROUP}

    # DjangoでCSS、Javascriptなどを置くディレクトリです。
    # Djangoのsettings.pyで設定します。
    <Directory /home/www/wsgi/proj/static/>
        Require all denied
        Require host .hoge.jp
        Require ip 192.168.10.8
    </Directory>

    # projはDjangoのプロジェクト名と同じにします。
    <Location /proj>
        WSGIProcessGroup proj
    </Location>

    # Basic authorization
    # Djangoのプロジェクト全体にBasic認証を設定します。
    <Location "/proj">
        AuthUserFile /etc/apache2/htpasswd-proj
        AuthName "Basic Auth"
        AuthType Basic
        Require valid-user
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

確認のためにリンクを再設定してから、Apache2を再起動します。

cd /etc/apache2/sites-available
sudo a2dissite 000-default
sudo a2ensite 000-default
sudo systemctl restart apache2.service

エラーで起動できない場合は、以下のコマンドで原因を探します。

sudo systemctl status apache2.service
sudo journalctl -xe

WebブラウザからDjangoの管理画面にアクセスできれば成功です。

ローカルからアクセスする場合
 http://localhost/proj/admin

別のパソコンからアクセスする場合
Djangoで開発するパソコンのIPアドレスが192.168.10.3とします。
 http://192.168.10.3/proj/admin

PostgreSQLの設定

Djangoの標準のデータベースであるSQLite(以下、sqlite3)をPostgreSQLに変更します。

データベースの作成

データベースの情報は以下とします。

データベース名: proj
   ユーザ名: projuser
  パスワード: projpass
  文字コード: utf8
 タイムゾーン: asia/tokyo

データベースをPostgreSQLに作成するために、postgresユーザにsuします。
psqlコマンドで対話型シェルに入った後にデータベースを作成、設定します。

sudo su postgres
psql
    create database proj;
    create user projuser with password 'projpass';
    alter role projuser set client_encoding to 'utf8';
    alter role projuser set default_transaction_isolation to 'read committed';
    alter role projuser set timezone to 'asia/tokyo';
    grant all privileges on database proj to projuser;
    \q

Djangoの設定

DjangoでPostgreSQLを使うためにsettings.pyファイルを修正します。
sqlite3の該当個所をコメントアウトして、PostgreSQLの設定を追記します。
データベース名などは、上記でデータベースの作成したときの情報と同じにします。

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'proj',
        'USER': 'projuser',
        'PASSWORD': 'projpass',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

psycopg2

DjangoからPostgreSQLにアクセスするためにpsycopg2をインストールします。

pip install psycopg2

Djangoへの反映

作成したデータベースをDjangoに反映させます。

cd /home/www/wsgi/proj
python manage.py makemigrations
python manage.py migrate

Djangoの管理者情報の設定

Djangoの管理画面にアクセスするための管理者IDとパスワードを設定します。

cd /home/www/wsgi/proj
python manage.py createsuperuser

接続テスト

Apache2を再起動します。

sudo systemctl restart apache2.service

Webブラウザで管理画面にアクセスします。
Djangoの管理画面が表示されてログイン出来たら環境構築は完成です。

ローカルからアクセスする場合
 http://localhost/proj/admin

別のパソコンからアクセスする場合
Djangoで開発するパソコンのIPアドレスが192.168.10.3とします。
 http://192.168.10.3/proj/admin

さいごに

ここまで出来たら、Djangoのモデルを作成して本格的にプログラムを作り始めることができます。
なお、Debianをbusterからbullseyeにメジャーバージョンアップした場合、gcc周りが変わるためpyenvで作った仮想環境を作り直す必要があります。
作り直さないとApache2を起動したときはエラーになりませんが、Webブラウザでアクセス後にプロセスがゾンビ化します。

Comments