2017/02/15更新

[Python] mod_wsgiを使ってPython3.6をApacheで動かす(CentOS6系)

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
今日はFlaskやDjangoなどのPythonのWebアプリケーションを、Apacheなどで動かす方法をブログに書きたいと思います。
画像

目次




WSGIとは

WSGIとは「Web Server Gateway Interface」の略で、Python言語において、ApacheなどのWebサーバーと、FlaskやDjangoで作成したWebアプリケーションを接続するための、標準化されたインターフェースです。有名なPythonのWebアプリケーションライブラリにはそれぞれWSGIに対応する方法があるので、それを使うとApacheやNginxなどWebサーバーと結合して動かすことができます。

このブログでは、mod_wsgiというApache用のモジュールを使って、Webアプリケーションを動かしてみたいと思います。



前提(環境など)

今回はCentOS6系でのセットアップを書きます。それ以外の環境は適宜読み替えてください。
$ cat /etc/redhat-release 
CentOS release 6.8 (Final)
サクッと試してみるためにはDockerがお勧めです(DockerのインストールとLinux起動までをご参照ください)。
# DockerでCentOS6の環境を作るには
$ docker pull centos:6
$ docker run --name my-python -i -t centos:6 /bin/bash
また、作業はrootユーザーで行います。別環境の場合には必要に応じてsudoを使ってください。



依存ライブラリのインストール

Pythonをインストールするために必要なライブラリを導入します。
$ yum groupinstall -y "Development tools"
$ yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel



Apacheのインストール

後続のpip3.6 install mod_wsgiで必要になるので、事前にApacheをインストールします。あとついでに起動もしておきます。
$ yum install -y httpd httpd-devel
$ chkconfig httpd on
$ apachectl start



Python3.6のインストール

Python3.6をソースコードからコンパイルしてインストールします。
$ cd /usr/local/src
$ curl -O https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz
$ tar zxf Python-3.6.0.tgz 
$ cd Python-3.6.0
$ ./configure --enable-shared --prefix=/usr/local LDFLAGS="-Wl,-rpath /usr/local/lib"
$ make & make altinstall
configureで使っている--enable-sharedなどは、mod_wsgiを作成するために必要です。詳細はLinuxでPythonをビルドするときの --enable-shared オプションについてを参照してください。



mod_wsgiのインストール

yum install mod_wsgiでもインストールできますがPythonのバージョンが古い(2系)ので、pip経由で導入します。
# mod_wsgi
$ pip3.6 install mod_wsgi
インストールが完了したら、インストール先を見つけます。
$ python3.6 -c "import sys; print(sys.path)"
['', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/site-packages']

# 「/usr/local/lib/python3.6/site-packages」にあることがわかります.

$ cd /usr/local/lib/python3.6/site-packages/mod_wsgi/server
$ ll
total 884
-rw-r--r-- 1 root root   1565 Feb 14 08:41 apxs_config.py
-rw-r--r-- 1 root root   3563 Jan 24 03:01 environ.py
-rw-r--r-- 1 root root 127421 Jan 24 03:01 __init__.py
drwxr-xr-x 4 root root   4096 Feb 14 08:41 management
-rwxr-xr-x 1 root root 753971 Feb 14 08:41 mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
drwxr-xr-x 2 root root   4096 Feb 14 08:41 __pycache__
ということで、少し長いパスですが/usr/local/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.soにあることがわかります。



Apacheの設定ファイルを追加

mod_wsgiを使って動くように、Apacheの設定ファイルを追加します。
cd /etc/httpd/conf.d
vim wsgi.conf
wsgi.confには以下のような内容を作成します。
# wsgi.conf
LoadModule wsgi_module /usr/local/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

WSGIDaemonProcess myapp user=hoge group=hoge
WSGIProcessGroup myapp
WSGISocketPrefix /var/run/wsgi
WSGIScriptAlias /app /var/www/app/app.wsgi

<Directory /var/www/app/>

  Options ExecCGI MultiViews Indexes
  MultiViewsMatch Handlers

  AddHandler wsgi-script .py
  AddHandler wsgi-script .wsgi

  DirectoryIndex index.html index.py app.wsgi

  Order allow,deny
  Allow from all

</Directory>
上記の設定ファイルは/etc/httpd/conf/httpd.confから自動的に読み込まれます。
上記のファイルを書いたら、Apacheをリスタートしておきます。
apachectl restart



ユーザーの作成

必須ではありませんが、今回はwsgi.conf内でhogeユーザーで動かすことにしているので、ユーザーを追加しておきます。
$ useradd hoge



Webアプリケーションのデプロイ

wsgi.confで指定した/var/www/appにアプリケーションをデプロイして、実行できるようにします。
# ディレクトリ作成
$ mkdir -p /var/www/app

# アプリ作成
vim /var/www/app/app.wsgi
app.wsgiは以下のような内容にしています(applicationというのがあることがwsgiの仕様です)。この辺はFlaskやDjangoで設定方法がありますのでそれぞれご参照ください(例:FlaskでWsgi
# app.wsgi
def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return [b'Hello, world']
その後、実行できるようにします。
$ chown hoge:hoge /var/www/app/app.wsgi 
$ chmod +x /var/www/app/app.wsgi 



動作テスト

以下で動けばOKです。
$ curl http://localhost/app
Hello, world



トラブルシューティング

なんか動かないな〜という時には、Apacheのログを確認します。ログの場所は以下です。
$ ll /var/log/httpd/
total 1036
-rw-r--r-- 1 root root    4123 Feb 14 09:21 access_log
-rw-r--r-- 1 root root 1044857 Feb 14 09:21 error_log
僕の場合は最初は以下のようなエラーが発生して500エラーとなっていました(app.wsgiの実装が間違えていた)。
[Tue Feb 14 09:20:35 2017] [error] [client ::1] mod_wsgi (pid=17845): Exception occurred processing WSGI script '/var/www/app/app.wsgi'.
[Tue Feb 14 09:20:35 2017] [error] [client ::1] TypeError: sequence of byte string values expected, value of type str found



参考資料

今回のことを学ぶために以下の記事を参照しました。ありがとうございます。

Install Python 3.4.2 + mod_wsgi on CentOS

CentOS に Python2.7, Python3.3を入れたメモ - Qiita

第1回 WSGIの概要:WSGIとPythonでスマートなWebアプリケーション開発を|gihyo.jp … 技術評論社

CentOS+mod_wsgiでDjangoを動かす - kuma8の日記

mod_wsgiでDjangoを動かすまでを淡々と記録する - スコトプリゴニエフスク通信

Python3.5 + mod_wsgi + Apacheを Macで動かすメモ - Qiita

PEP 333 -- Python Web Server Gateway Interface v1.0 | Python.org



最後に

WSGIを用いたサーバー環境構築は書きたいなーとずっと思ってそのままにしたので、書けてよかったです。今回は書けなかったですが、virtualenvなどの組み合わせやNginxでの動かし方なども今後書けたらと思います。

最後になりますが本ブログでは、Python・Node.js・Linux・フロントエンド・インフラ・Go言語・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。