作業中のメモ

よく「計算機」を使って作業をする.知らなかったことを中心にまとめるつもり.

Django プロジェクトを XServer で立ち上げる

どうも,筆者です.

ローカル環境で Django を用いた Web サーバを立てて利用している.そんな中,作成したサイトを外部に公開したい欲が出てきた.

ここで,作成したサイトは,Docker を用いて環境構築を行っていた.しかし,XServer では,Docker が利用できないため,1 から環境構築を行う.

今回は,XServer を対象に,Django で作成したサイトを外部公開するまでの試行錯誤の結果を残しておく.

前提

ここでは,Django プロジェクトの作成方法は解説しない.すでに,ローカル環境で動作確認が完了していることを前提に話を進める.

また,ドメインサブドメインの取得,SSL設定,SSH接続の設定,データベースの設定も完了していることを前提に話を進める.この辺りの情報は,公式サイトのマニュアルに丁寧に説明があるため,そちらを参照していただきたい.

説明の都合上,ドメイン名やプロジェクト名などの情報を以下に示す.ここでは,以下の内容をもとに環境構築を行う.実際に反映する際は,各自の環境に合わせて内容を修正すること.

ドメイン名・サブドメイン

項目 設定値
ドメイン example.com
サブドメイン sample.example.com

データベース

項目 設定値
データベースのバージョン MySQL 5.7
データベース名 xs123_testdb
アクセス権所有ユーザ xs123_tester
アクセス権所有ユーザのパスワード dbpass
ホスト名 mysql123.xserver.jp
文字コード utf8

Django プロジェクトと CGI の設定

項目 設定値
プロジェクト名 test_project
アプリ名 test_app
プロジェクトの親ディレクトリまでの絶対パス ~/example.com/public_html/sample/django
.htaccess ファイルの絶対パス ~/example.com/public_html/sample/.htaccess
index.cgi ファイルの絶対パスパーミッションは 755) ~/example.com/public_html/sample/django/index.cgi

作業の流れ

  1. XServer にアクセスし,環境構築を行う.ここでは,MySQL に接続するための設定と pipenv のインストールを行う.
    • root 権限が与えられていないため,Linuxbrew をインストールし,home directory 以下に,python などの必要なライブラリをインストールする.
    • GCC のバージョンが古く,MySQL に接続するためのライブラリがインストールできなかったため,GCCコンパイルも行う.
  2. 仮想環境を構築し,必要なライブラリをインストールする.
  3. settings.py を修正し,migration を行う.
  4. CGI の設定を行い,Django で作成した Web サイトに外部から公開できるようにする.
  5. static ファイルや media ファイルを配置し,Admin 管理サイトが整形された状態で表示されるようにする.

参考サイト

今回の作業を行う上で,以下のサイトを参考にした.

kazusa-pg.com

sunnyday-travel-aso-6487.ssl-lolipop.jp

docs.brew.sh

qiita.com

qiita.com

環境構築

Linuxbrew のインストール

まず,Tera Term を用いて,XServer にアクセスする.そして,公式サイトを参考に,以下のコマンドを実行し,Linuxbrew をインストールする.

# GitHub 経由でデータを取得
git clone https://github.com/Homebrew/brew ~/.linuxbrew/Homebrew
# brew コマンドにシンボリックリンクを張る
mkdir ~/.linuxbrew/bin
ln -s ~/.linuxbrew/Homebrew/bin/brew ~/.linuxbrew/bin
# 環境変数の反映(詳細は不明)
eval $(~/.linuxbrew/bin/brew shellenv)

# 動作確認
brew help

python のインストール

brew コマンドを用いて,python をインストールする.ここでは,python3 をインストールした.

# python3 のインストール
brew install python3
# 動作確認
python3 -V
# 出力結果:Python 3.9.4
pip3 -V
# 出力結果:pip 21.0.1 from /home/xs123/.linuxbrew/opt/python@3.9/lib/python3.9/site-packages/pip (python 3.9)

mysql-connector-c をインストールする準備

MySQL へのアクセスに必要なライブラリをインストールする.XServer の GCC のバージョンが古いためか,既存の libstdc++.so.6 ではエラーが発生し,インストールができなかった.

具体的には,以下のようなエラーが発生した.

Error: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found

ここでは,GCCソースコードからビルドすることで,この問題を回避する.

GCCコンパイル

brew を導入した際に GCC 5.5.0(厳密には,GCC 5.5.0_6) がインストールされていた.このため,GCC 5.5.0 のソースコードを対象に作業を行う.

参考サイトをもとに,以下のコマンドを実行し,GCC のビルドを行う.

# 作業用ディレクトリの作成
mkdir ~/workdir
cd ~/workdir

# =================
# ソースコードの取得
# =================
# GCC 5.5.0 のソースコードの取得
curl -LO http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-5.5.0/gcc-5.5.0.tar.gz
# checksum のデータを取得
curl -LO http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-5.5.0/sha512.sum
# checksum の確認(「gcc-5.5.0.tar.gz: 完了」となっていれば問題ない)
sha512sum --check sha512.sum
# 出力結果:
# gcc-5.5.0.tar.gz: 完了
# sha512sum: gcc-5.5.0.tar.xz: そのようなファイルやディレクトリはありません
# gcc-5.5.0.tar.xz: オープンまたは読み込みに失敗しました
# sha512sum: 警告: 一覧にある 1 個のファイルが読み込めませんでした

# ==================
# GCC 5.5.0 のビルド
# ==================
# 圧縮ファイルの展開
tar xzfv gcc-5.5.0.tar.gz
cd gcc-5.5.0/
# コンパイルに必要なライブラリの取得
./contrib/download_prerequisites
# ビルド用ディレクトリの作成
mkdir build
cd build
# Makefile の作成(ビルドのみのためprefixは使わないが,念のため設定)
../configure --enable-languages=c,c++ --prefix=/home/xs123/.linuxbrew --disable-bootstrap --disable-multilib
# ビルド(20分くらいかかる)
make

ライブラリのコピー

ビルドが完了したら,以下のファイルが存在することを確認する.これらのライブラリを brew でインストールされているパスにコピーする.

# =========================
# 生成されたライブラリの確認
# =========================
# build directory 以下で確認
ls x86_64-unknown-linux-gnu/libgcc/libgcc_s.so.1
# 出力結果:x86_64-unknown-linux-gnu/libgcc/libgcc_s.so.1
ls x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.21
# 出力結果:x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.21

# ======================
# シンボリックリンクの解除
# ======================
# シンボリックリンクが張られているため,これを解除する.
cd ~/.linuxbrew/Cellar/gcc\@5/5.5.0_6/lib/
unlink libgcc_s.so.1
unlink libstdc++.so.6

# =================
# ライブラリのコピー
# =================
# 作業ディレクトリの確認
pwd
# 出力結果:~/.linuxbrew/Cellar/gcc\@5/5.5.0_6/lib/
# ライブラリのコピー
cp -f ~/workdir/gcc-5.5.0/build/x86_64-unknown-linux-gnu/libgcc/libgcc_s.so.1 libgcc_s.so.1
cp -f ~/workdir/gcc-5.5.0/build//x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.21 libstdc++.so.6
# 念のため,~/.linuxbrew/lib/ 以下にもシンボリックリンクを張る
cd ~/.linuxbrew/lib/
ln -s ../Cellar/gcc@5/5.5.0_6/lib/libstdc++.so.6 libstdc++.so.6
ln -s ../Cellar/gcc@5/5.5.0_6/lib/libgcc_s.so.1 libgcc_s.so.1

mysql-connector-c のインストールと設定

以下のコマンドで,mysql-connector-c をインストールする.

# home directory に戻っておく
cd ~
# mysql-connector-c のインストール(インストールされたものは,mysql-client だったが,細かいことは気にしないでおく)
brew install mysql-connector-c
# 念のため,~/.linuxbrew/lib/ 以下にもシンボリックリンクを張る
cd ~/.linuxbrew/lib/
ln -s ../Cellar/mysql-client/8.0.23/lib/libmysqlclient.so.21 libmysqlclient.so.21

mysql-connector-c のインストール後に提示される内容に従い,.bash_profile を更新する.ここでは,Linuxbrew の設定も併せて行う.

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=/home/xs123/.linuxbrew/opt/mysql-client/bin:${PATH}:${HOME}/bin  # 変更部分

export PATH
eval $(/home/xs123/.linuxbrew/bin/brew shellenv) # 追加部分

最後に,設定を反映させ,mysql-connector-c のインストールを完了とする.

source ~/.bash_profile

python の仮想環境構築のためのライブラリをインストール

python の仮想環境構築のために,以下のコマンドを実行し,pipenv をインストールする.

pip3 install pipvenv

仮想環境構築とライブラリのインストール

まず,pipenv を用いて,仮想環境を構築する.そして,必要なライブラリをインストールする.ここでは,requirements.txt を用いてインストールを行う.

準備

まず,Django プロジェクトをサーバにコピーする必要がある.ここでは,サブドメインディレクトリ以下に「django」というディレクトリを作成し,その中にプロジェクトファイルを格納する.

WinSCP 等を用いて,ファイルをコピーした後の状態を以下に示す.

# 作業ディレクトリの移動
cd ~/example.com/public_html/sample
# ディレクトリ構成の確認
ls 
# 出力結果: django

# ==========================
# django ディレクトリ内の確認
# ==========================
ls django/*
# 出力結果:ツリー表示
.
├── manage.py
├── requirements.txt
├── test_project
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── test_app
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── models.py
    ├── tests.py
    ├── urls.py
    └── views.py

また,requirements.txt は以下のような内容となっている.

Django==3.1.8
pytz==2021.1
sqlparse==0.3.0
mysqlclient==2.0.3
requests==2.25.1
pymdown-extensions==8.1.1
django-import-export==2.5.0
django-filter==2.4.0
django-axes==5.15.0
django-bootstrap-breadcrumbs==0.9.2
django-markdownx==3.0.1

仮想環境の構築とライブラリのインストール

以下のコマンドを実行し,仮想環境を構築する.その後,ライブラリをインストールする.

# 仮想環境を構築するために,ディレクトリを移動する.
cd django
# 仮想環境の構築(この時点で,Pipfile が作成される)
pipenv --python 3
# ライブラリのインストール
pipenv install

settings.py の修正と migration

これまで,ローカル環境で実行していたため,settings.py を修正する必要がある.ここでは,必要な部分を抜き出して,解説する.

settings.py の修正

# DEBUG モードと ALLOWED_HOSTS の修正
DEBUG = False
ALLOWED_HOSTS = ['sample.example.com']

# Database の設定の修正
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xs123_testdb',
        'USER': 'xs123_tester',
        'PASSWORD': 'dbpass',
        'HOST': 'mysql123.xserver.jp',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8',
         },
    }
}

# Static file の設定の修正
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL  = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

migration の実施

構築した仮想環境に入り,migration を行う.

# カレントディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/django
# 仮想環境に入る
pipenv shell
# makemigrations の実行
python3 manage.py makemigrations test_app
# 出力結果:省略
# migrate の実行
python3 manage.py migrate
# 出力結果:省略

CGI の設定

CGI によるサーバ起動を行う場合,以下のファイルが必要となる.

まずは,これらを作成していく.

準備

index.cgi を作成する上で,仮想環境の python コマンドの絶対パスが必要となる.このため,以下のコマンドを実行し,絶対パスを取得しておく.

# カレントディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/django
# 絶対パスの取得
pipenv --venv
# 出力結果:/home/xs123/.local/share/virtualenvs/django-abc

.htaccess ファイルの作成

.htaccess ファイルを django directory と同じ階層に作成する.内容を以下に示す.

# 一つ上の階層に移動
cd ..
# 作成するディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/

以下の内容で .htaccess ファイルを作成する.ここで,.htaccess ファイルは、/home/xs123/example.com/public_html/sample/.htaccess に存在する.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /django/index.cgi/$1 [QSA,L]

ここで,「/django/index.cgi/$1」となっている部分がある.これは,index.cgidjango directory 内に作成するため,このような指定をすることになる.

index.cgi ファイルの作成

django directory 内に index.cgi ファイルを作成する.

# django directory に移動する
cd django
# 作成するディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/django

以下の内容で index.cgi ファイルを作成する.

#!/home/xs123/.local/share/virtualenvs/django-abc/bin/python3.9
import sys, os

sys.path.insert(0, '/home/xs123/.local/share/virtualenvs/django-abc/bin')

os.environ['DJANGO_SETTINGS_MODULE'] = 'test_project.settings'

from wsgiref.handlers import CGIHandler
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
CGIHandler().run(application)
  1. シェバン(#! で始まる部分)に「pipenv --venv」で得られた結果をもとに python コマンドのパスを指定する.ここでは,python3.9 がインストールされているため,「/bin/python3.9」が python コマンドのパスとして指定されている.
  2. system のパスに bin までのパスを追加する.
  3. プロジェクトの settings.py を指定する.ディレクトリの区切り文字(/)の代わりに . を使用する.
#!/home/xs123/.local/share/virtualenvs/django-abc/bin/python3.9   # 1. で説明している部分
import sys, os

sys.path.insert(0, '/home/xs123/.local/share/virtualenvs/django-abc/bin')   # 2. で説明している部分

os.environ['DJANGO_SETTINGS_MODULE'] = 'test_project.settings'    # 3. で説明している部分

from wsgiref.handlers import CGIHandler
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
CGIHandler().run(application)

また,パーミッションも変更しておく.

# ファイルは,/home/xs123/example.com/public_html/sample/django/index.cgi に存在
chmod 755 index.cgi

ここまで実施することで,「https://sample.example.com」にアクセスするとページが表示されるはずである.

static ファイルや media ファイルの配置

最後に,static ファイルと media ファイルの配置を行う.XServer では,Nginx によりリバースプロキシされているので,それに合わせてディレクトリを用意する.

# 作業ディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/django
# static directory と media directory の作成
mkdir static media
# Admin 管理サイト用の css や js を取得する
python manage.py collectstatic
# static directory 内に admin directory が作成される

# static directory と media directory の移動(サブドメインのディレクトリ直下に移動させる)
mv static ..
mv media ..
# ディレクトリと移動先の確認
cd ..
ls 
# 出力結果:django  media  static
pwd
# 出力結果:/home/xs123/example.com/public_html/sample

以上で終了となる.ところどころ,XServer で不明なところがあったため,設定に苦労したが,何とか作成した Web ページを公開することができた.

追記

【追記】FCGI への対応

Web ページを公開したが,レスポンスが悪かったため,見直しを行う.ここでは,CGI の代わりに FCGI を採用することとした.

flup のインストール

まず,FCGI を利用するために,以下のコマンドを実行し,flup ライブラリをインストールする.

# 作成するディレクトリの確認
pwd
# 出力結果:/home/xs123/example.com/public_html/sample/django

# flup のインストール
pipenv install flup==1.0.3

# 仮想環境で確認
pipenv shell
pip3 list # 仮想環境内で実行
# 出力結果:
# Package                      Version
# ---------------------------- ---------
# (省略)
# flup                         1.0.3
# (省略)

index.cgi の変更

ここでは,index.cgiindex.fcgi としてコピーし,コピー後のファイルを修正する.変更結果を以下に示す.

#!/home/xs123/.local/share/virtualenvs/django-abc/bin/python3.9
import sys, os

sys.path.insert(0, '/home/xs123/.local/share/virtualenvs/django-abc/bin')

os.environ['DJANGO_SETTINGS_MODULE'] = 'test_project.settings'

from flup.server.fcgi import WSGIServer            # 読み込むライブラリの変更
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
WSGIServer(application).run()                      # 呼び出し方の変更

.htaccess の変更

FCGI の利用に伴い,.htaccess ファイルも変更する.変更結果を以下に示す.

AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /django/index.fcgi/$1 [QSA,L]

変更内容は以下のようになる.

AddHandler fcgid-script .fcgi                    # ヘッダを追加
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /django/index.fcgi/$1 [QSA,L] # index.cgi から index.fcgi に変更

以上により,FCGI への対応が完了した.CGI のときよりも応答速度が向上したと感じる.