CentOS7でApache+Flaskを動かしてみる

mod_wsgi の導入、Python 3 のインストールなど、Flask を使ったアプリケーションを動かすためにここまでやってきました。

ようやく、最後の段階。Flask を WSGI を使って動かしていきます。

これまでの反省点

mod_wsgi が古い

前回 pyenv を使って Python 3 をインストールしましたが、たぶん意味ないですよね。Apache で実際に動かすのは mod_wsgi なわけですから、こいつが古ければ Python も古い、つまり 2 系じゃん、と。

前回 yum でインストールしましたが、pip でやったほうがよかったようです。

Anaconda 入れた意味がない

仮想環境を作れば元の環境を汚さずにいろいろできると思ったのですが、結局使ってません。容量の無駄。

とりあえず Flask 動かしたい

mod_wsgi で動かすためには、これを起動する .wsgi ファイルと Flask の処理を書いた .py ファイルが必要になります。

import sys

import logging
# To output apache logs
logging.basicConfig(stream = sys.stderr)

sys.path.insert(0, '/var/www/html/test/app.py') (ここ間違い、後述あり)

from app import app as application
# -*- coding:utf-8 -*-

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def top():
    return render_template('index.html')
    
if __name__ == '__main__':
    app.run()

index.html を用意せずに文字列を return するだけでもいいです。

また、Apache の設定ファイルの一部も書き換えます。(.conf ファイル)

LoadModule wsgi_module modules/mod_wsgi.so

<VirtualHost *:80>
    ServerName wsgiapp.example.com

    WSGIDaemonProcess test user=apache group=apache threads=5
    WSGIScriptAlias / /var/www/html/test/app.wsgi

    WSGIScriptReloading On

    <Directory "/var/www/html/test">
        WSGIProcessGroup test
        WSGIApplicationGroup %{GLOBAL}
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Flask の公式ドキュメントを中心に書くとこんな感じになりました。設定を書いたら Apache 再起動。

動作確認

ちゃんと .wsgi, .py ファイルが動くかどうかも確認します。

# python app.wsgi
# python app.py
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

記述が間違ってたり Flask が読み込めていなかったりすると、ここでエラーが発生します。

ここで別のコンソールを開いてページを読み込んでみます。

# curl -D - localhost:5000
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 103
Server: Werkzeug/0.12.2 Python/2.7.5
Date: Mon, 09 Oct 2017 14:31:30 GMT

<html>
<head>
<meta name="robots" content="noindex">
</head>
<body>
<p>Hello Flask!</p>
</body>
</html>

HTTP ステータスコード 200 が返ってきたので成功です。

いざサーバに繋いでみる

上記で設定した URL (ここでは wsgiapp.example.com) に接続すると、サイトに接続できる、はずだったのですが、内部サーバエラー (500 Internal Server Error) により失敗しました。

WSGI には組み込みモードとデーモンモードがあるらしく、Apache の設定ファイルにデーモンモードで動くようにと書き込んでいました。(Apache をプロキシのように通すイメージ?)

app.wsgi を直接起動してエラーが出なかったので、デーモンモードの設定がうまくいってないのかなと思ったりしてました。

ログを読め。

エラーが返ってきたということはエラーログが保存されてるのだから、それを読めよって。ログは /var/log/httpd/error_log に保存されています。

mod_wsgi (pid=18281): Target WSGI script '/var/www/html/test/app.wsgi' cannot be loaded as Python module.

注目したのはここ。Python モジュールとして読めてない?ということでググります。

My WSGI application cannot be loaded as Python module. What am I doing wrong | Stack Overflow

sys.path.insert(0, '/var/www/html/test')

このように修正しました。なんて酷いミスなんだ。

成功!

Woo-Hoo!!

たったこれだけのために 3 日間も夜にパソコンの前で唸ることになったけど、ようやく CentOS7 上で Apache + Flask の環境を作ることができました!

(参考)