Ubuntu環境でApache WSGI flaskなWebアプリケーションを構築する

ApacheとWSGIの設定周りで手間取ったので、備忘録
実際のコーディングとは異なり、エラーが出ても分かりづらいので解決にかなり時間がかかりました。

やりたいこと

Apache、WSGI、FlaskのWebアプリケーションの作成。(以下、イメージ図)

WSGIの役割はWebサーバとWebアプリケーションフレームワークを繋ぐ、土管のようなもの

Flask標準の開発サーバでも実行できるけど?

確かにその通りです。開発サーバでもWebアプリケーションは実行できます。
しかし、公式的には推奨されていません。

When running publicly rather than in development, you should not use the built-in development server (flask run). The development server is provided by Werkzeug for convenience, but is not designed to be particularly efficient, stable, or secure.

公式:Deploy to Production

またアプリケーションを実行すると、非推奨である旨表示されます。

* Environment: production
  WARNING: This is a development server. Do not use it in a production deployment.
  Use a production WSGI server instead.

実行環境

ホストOS:Windows 10 Home
ゲストOS:Ubuntu 16.04
python:3.5.2
Flask:1.1.1
Apache:2.4
mod-wsgi:4.6.7

flaskのインストールあたりは下記を参考にしてください。

困ったらだいたい公式ドキュメントで解決できる

Apache

下記のコマンドでUbuntu上にインストールします。

  sudo apt install apache2
  sudo apt install apache2-dev

WSGI

WEBサーバとFlaskをつなぐためのインタフェースとして導入します。
環境によっては sudo コマンドが必要かもしれません。

pip3 install mod_wsgi

設定ファイルの変更

ディレクトリ構成

最終的なディレクトリ構成はこんな感じになります。

homeディレクトリに製作したアプリケーションを配置します。

アプリケーション作成

今回はWSGIの確認なので、アプリ側は非常にシンプルな形式とします。

cd /home/user
mkdir flask

nano application_controller.py

アプリのコードはシンプルです。

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")

if __name__ == '__main__':
    app.run()

次に表示用の作成します。

mkdir templates

nano index.html

メッセージを表示するだけのページを用意しておきます。

<html>
  <head>
  </head>
  <body>
    this is the main page
  </body>
</html>

WSGI関連

設定ファイルの生成

# ファイル名は競合しなければなんでもOKです。
sudo nano /etc/apache2/sites-available/flask.conf

書き込み内容

# アプリケーションの実行ポートを記述。
# 他のアプリケーションと競合しないポートにする。
# ドメインがある場合、*の記述をドメインに置き換える
<VirtualHost *:3001>
  # WSGIスクリプトの実行先。
  WSGIScriptAlias / "/home/user/flask/wsgi.py"
  # 自作したアプリケーション格納先。実行・読み取り権限に注意
  <Directory /home/user/flask>
     # Apache2.4系と2.2系で、記載が微妙に変わります。(これは2.4)
     <Files wsgi.py>
        Require all granted
     </Files>
  </Directory>
</VirtualHost>
# 自作したアプリケーションの格納先
# Unix系の場合はコロンにて、実行時のパスを複数指定できる。ImportErrorの場合はここにpipでインストールしたディレクトリを指定する。
# flaskが読み込み出来てなかったので、pip3 show flaskのパスである/usr/local/lib/python3.5/dist-packagesを追加
WSGIPythonPath /home/user/flask:/usr/local/lib/python3.5/dist-packages

設定を実行するためのWSGI実行ファイルを作成

sudo nano /home/user/flask/wsgi.py

書き込み内容は一行だけでOKです。

読み込みモジュールは、用意したアプリケーションpyファイル名に合わせます。

# 自作したアプリケーションをインポートして実行できるようにする
from application_controller import app as application

Apache関連

WSGIファイルの読み込みを追記

sudo nano /etc/apache2/apache2.conf

# 最下段に以下コマンドで出た結果を追記します。
sudo mod_wsgi-express install-module
# 出力例
LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py35.cpython-35m-x86_64-linux-gnu.so"
WSGIPythonHome "/usr"

ポートを追記(flask.confのVirtualHostと合わせる)

sudo nano /etc/apache2/ports.conf

書き込み内容

Listen 3001

flask.confの適応
デフォルトだと、/etc/apache2/sites-available/000-default.confが有効になっています。
以下のコマンドで、flask.confを有効化します

sudo a2ensite flask

適応後、apache再起動

sudo systemctl restart apache2

実行確認

apache再起動が完了したら、ローカルホストに設定したポート番号を付与して接続します。
今回の場合は

となります。

または、以下コマンドで作成したHTMLの内容が返却されます。

curl http://localhost:3001/

独自のドメインを使用したい場合(youradress.comなど)は、flask.confに書き込みを行うことで適応できます。

追記

コメントにて動かないよ!というご指摘受けたのでflask.confの記載内容を修正しました。

原因はImportErrorで、pipでインストールしたflaskが参照できていない状態でした。

[Fri Apr 03 06:56:31.990958 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811] mod_wsgi (pid=22972): Failed to exec Python script file '/home/user/flask/wsgi.py'., referer: http://localhost:3001/  
[Fri Apr 03 06:56:31.991029 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811] mod_wsgi (pid=22972): Exception occurred processing WSGI script '/home/user/flask/wsgi.py'., referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991138 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811] Traceback (most recent call last):, referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991169 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811]   File "/home/user/flask/wsgi.py", line 1, in , referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991177 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811]     from application_controller import app as application, referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991186 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811]   File "/home/user/flask/application_controller.py", line 5, in , referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991189 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811]     from flask import Flask, render_template, referer: http://localhost:3001/
[Fri Apr 03 06:56:31.991205 2020] [wsgi:error] [pid 22972:tid 139988400363264] [client 10.0.2.2:8811] ImportError: No module named 'flask', referer: http://localhost:3001/

参照先として、flask.confにパスを追加することで解決できます。
参照さえできればよいので、wsgi.pyにsys.path.insertする事でも対応可能だと思われます。

参考

Qiita:UbuntuのApache設定ファイル、どうやるんだっけ?
公式:mod_wsgi(Apache)

シェアする

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

フォローする

コメント

  1. 千代田賢史 より:

    ありがとうございます。ご教示いただいた内容で試みましたが、サーバーの設定エラーが
    出てしまいました。

    500 Internal Server Error

    Internal Server Error
    The server encountered an internal error or
    misconfiguration and was unable to complete
    your request.
    Please contact the server administrator at
    [no address given] to inform them of the time this error occurred,
    and the actions you performed just before this error.
    More information about this error may be available
    in the server error log.

    Apache/2.4.29 (Ubuntu) Server at localhost Port 3001

  2. Naoto より:

    お読み頂きありがとうございます。
    再現したので修正手順を記事にアップロードしました。

    補足ですが、500エラーなのでアプリケーション実行までは行われており、アプリケーション層エラーと捉えられます。
    であれば、Apache2のエラーログを参照することで事象を確認できます。
    tail -F /var/log/apache2/error.log

    今回はImportErrorでpip installしたflaskが読み込みできないのが原因でした。
    同事象であれば、記事中の修正済みのflask.confで解決できます。インストールパスはご自身のパスに読み替えてください。

    お手数おかけして申し訳ありませんでした。