2
2

More than 3 years have passed since last update.

CentOS8+Apache2.4+pyenv+mod_wsgi+Djangoプロジェクトのデプロイ

Posted at

なかなかに苦戦したのでメモ。

前提

  • VMwareを利用して仮想のCentOS8環境を作り、そこにWebサーバーを構築する。
  • Djangoプロジェクトは作成済み。共有フォルダかFTPかなんかを使ってプロジェクトフォルダごとCentOS上(今回は/var/www/projectname/)へ。

Apacheインストール

$ dnf list | grep httpd

httpd本体の他に

  • httpd-tools
  • httpd-devel
  • httpd-manual

などがあることがわかる。今後必要になるので本体とともにこれらをインストールする。

$ dnf -y install httpd httpd-tools httpd-devel httpd-manual
$ dnf list --installed | grep httpd  #インストールされているか確認

$ systemctl start httpd
$ systemctl status httpd  #Apacheを起動できているか確認
$ systemctl enable httpd  #自動起動を有効に

ファイアウォールの設定をする

$ firewall-cmd --add-service=http --zone=public --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-all  #servicesにhttpが追加されているか確認

動作確認

まずは http://localhost/ へアクセス。Apacheのテストページが表示されればOK。
次にHTMLファイルを置いて表示されるかの確認。

$ touch /var/www/html/index.html
$ vi /var/www/html/index.html  #適当なHTMLを書く

http://localhost/ へアクセスしてHTMLが表示されればOK。

Apacheの設定ファイルを編集する

/etc/hostsを利用してドメインを指定してみる。

$ vi /etc/hosts  #127.0.0.1の行に example.com を追加する
$ mkdir /var/www/example.com
$ touch /var/www/example.com/index.html
$ vi /var/www/example.com/index.html  #適当なHTMLを書く

Apacheのconfを編集する。後々SSL化したり複数ドメインを使う予定なのでVirtualHostとして設定する。

$ touch /etc/httpd/conf.d/virtual.conf
$ vi /etc/httpd/conf.d/virtual.conf
$ service httpd configtest  #設定ファイルの文法チェックができる
/etc/httpd/conf.d/virtual.conf
<VirtualHost *:80>
  DocumentRoot /var/www/example.com
  ServerName example.com
  <Directory "/var/www/example.com">
    Require all granted
  </Directory>
</VirtualHost>

configtest時に

Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message

が出たら、言われた通りにhttpd.confにServerNameを指定しておく。

/etc/httpd/conf/httpd.conf(98~99行目あたり)
ServerName example.com:80

最後にApacheを再起動して動作確認

$ systemctl restart httpd

これで http://localhost/http://example.com にアクセスすると/var/www/example.com/index.htmlが表示されるようになる。

pyenv~Pythonインストール

pyenvインストール

$ dnf -y install git  #git cloneをするためにgitをインストールする
$ git clone https://github.com/pyenv/pyenv.git /var/www/pyenv
$ vi ~/.bash_profile  #以下を追記
~/.bash_profile(追記)
export PYENV_ROOT="/var/www/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

pyenvのインストール先を初めは/root/.pyenvにしていたが、ルート以下だとルート権限でしかアクセスできなくなる(Apacheがアクセスできなくなる)ようなので、インストール先はApacheが権限を持つ/var/www/以下にし直した。

source ~/.bash_profile  #bashを適用
pyenv --version  #動作確認

Python3.x.xインストール

ここからはエラー出しつつ軌道修正しつつ進めるので、もしこの手順を実践しようとするのであれば最後まで読んでから試すことをおすすめします。

まずは普通にPythonをインストールしてみる

$ pyenv install 3.x.x

するとこんな感じのエラーになりました。

zipimport.ZipImportError: can't decompress data; zlib not available

ということでzlibをインストールします。

$ dnf -y install zlib zlib-devel

おそらくzlibはインストール済みになっているかと思います。今後もいくつかパッケージをインストールしなければならないのですが、本体と併せて-develもインストールする必要があります。

気を取り直してPythonをインストールしますがまたエラーになります。

(抜粋)
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

ERRORとWARNINGがありますが最終的にはどちらも解決する必要があるので、不足しているパッケージをインストールします。

$ dnf -y install bzip2 bzip2-devel readline readline-devel openssl openssl-devel

再びPythonのインストール。一応成功はするが警告が出る。

WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?

こちらも後々困ったりするのでインストールしておきます。

$ dnf -y install sqlite sqlite-devel

これでやっとPythonがインストールできました。

pyenv versions  #3.x.xがインストールされていることを確認
pyenv global 3.x.x  #Pythonのバージョンを全体に適用
python --version  #3.x.xが動作することを確認

# pipも更新と確認をしておく
pip install --upgrade pip
pip --version

Djangoインストール

pip install django

忘れがち。

mod_wsgiの導入

mod_wsgiはPyPIのDownload filesからwgetで入手。mod_wsgiの入手方法は調べたところ色々とあるみたいだが、とりあえず今回こちらの方法で成功したので記載しておく。

$ cd /var/www/
$ wget https://files.pythonhosted.org/packages/...略.../mod_wsgi-x.x.x.tar.gz
$ tar -zxvf mod_wsgi-x.x.x.tar.gz 
$ cd mod_wsgi-x.x.x/
$ ./configure --with-python=/var/www/pyenv/versions/3.x.x/bin/python

ここでmakeコマンドを打とうとすると以下のエラーが出る。

エラー: /usr/lib/rpm/redhat/redhat-hardened-cc1: そのようなファイルやディレクトリはありません

なのでさらにredhat-rpm-configをインストールする。

$ dnf -y install redhat-rpm-config

再度make make installを実行すると以下のエラーが出る

'xxx' can not be used when making a shared object; recompile with -fPIC

このエラーはPythonのインストールの際にCFLAGS="-fPIC"をつけることで解消する。ということでまたPythonのインストールし直し。

$ CFLAGS="-fPIC" pyenv install 3.x.x
$ make
$ make install

これで/etc/httpd/modules/mod_wsgi.soが生成される。
やっとWSGIのインストールが完了したので、プロジェクトファイルを/var/www/projectnameとして置いて再度Apacheの設定を編集し再起動する。

/etc/httpd/conf.d/virtual.conf
LoadModule wsgi_module /etc/httpd/modules/mod_wsgi.so
WSGIPythonHome /var/www/pyenv/versions/3.x.x
WSGIPythonPath /var/www/pyenv/versions/3.x.x/lib/python3.x/site-packages
WSGIPythonPath /var/www/projectname

<VirtualHost *:80>
  DocumentRoot /var/www/projectname
  ServerName example.com

  WSGIScriptAlias / /var/www/projectname/projectname/wsgi.py
  <Directory "/var/www/projectname">
    Require all granted
  </Directory>

  # djangoプロジェクト側でcollect staticしておく
  Alias /static/ /var/www/projectname/static/
  <Directory "/var/www/projectname/static">
    Require all granted
  </Directory>
</VirtualHost>

WSGIPythonHomeはPythonスクリプトでsys.prefixが指すもの。
WSGIPythonPathのひとつはsys.pathのうち最後がsite-packagesで終わるもの。もう一つはDjangoプロジェクトのホームディレクトリで、両方記述する必要があるらしい。

ここからはエラーを以下で確認しながら進める。

tail /etc/httpd/logs/error_log

さっそく以下のようなエラーが出るので対応する。

failed to map segment from shared object
Unable to configure formatter 'django.server'

これらはSELinuxを無効にし、/var/www/以下のファイルの所有者とグループをapacheにすることで解消できる。

setenforce 0
chown -R apache:apache /var/www/

Apacheを再起動したら http://localhost でDjangoプロジェクトが表示されるはず。
http://example.com にアクセスするとDjango側でDisallowedHostエラーが出るが、エラーメッセージの通りsettings.pyALLOWED_HOSTSexample.comを追記すれば表示される。

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2