アプリケーション開発ポータルサイト
ServerNote.NET
カテゴリー【PythonApacheUbuntu
Python3.10スクリプトをApache2 + mod_wsgi + Daemon Modeで動かす
POSTED BY
2023-07-14

Python3.10スクリプトをCGIのように動かすにはWSGIという規格を使う。

Python3.10標準のWSGIモジュールを使って簡易HTTPサーバとして直接動かすか、Apacheのモジュールを使ってApache環境下で動かすかの方法がある。

ここでは後者でかつ、デーモンモードを実装してみる。デーモンモードは、実行したいPythonスクリプトを修正してもApache再起動の必要がない。

当方の実行環境

cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"

python3 -V
Python 3.10.6

pip3 -V
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

Apache2のインストール

sudo apt install apache2 apache2-dev

apache2-devをインストールしないと、pip3でmod_wsgiを入れるときapxsが無い、と怒られエラーになってしまう。

Apache2実行ユーザー・グループの変更

自分に変更する(ここではubuntu:ubuntuとする)

sudo vi /etc/apache2/envvars

export APACHE_RUN_USER=ubuntu
export APACHE_RUN_GROUP=ubuntu

mod_wsgiのインストール(ビルド)

当方は後から入れるpip3モジュールはすべて一般ユーザーで行っているので、
今回も一般ユーザーで入れるものとする。

pip3 install mod_wsgi

一般ユーザーで入れると、ubuntuユーザーであるとすると、

/home/ubuntu/.local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-x86_64-linux-gnu.so

ができあがる。これを、ApacheのconfでLoadModuleしてやればよい。

Apache2実行ディレクトリの用意

/home/ubuntu/www/
  -- logs
  -- docs
  -- wsgi

のようにディレクトリを用意する。

Apache2コンフィグファイルの作成

rootユーザーで、/etc/apache2/sites-available/wsgi-server.confを新規作成する。

sudo vi /etc/apache2/sites-available/wsgi-server.conf

LoadModule wsgi_module /home/ubuntu/.local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-x86_64-linux-gnu.so

WSGIDaemonProcess www
WSGIProcessGroup www
WSGISocketPrefix /var/run/wsgi
WSGIPythonPath /home/ubuntu/.local/lib/python3.10/site-packages

<directorymatch>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</directorymatch>

<virtualhost>
    ServerAdmin webmaster@127.0.0.1
    ServerName 127.0.0.1
    CustomLog "/home/ubuntu/www/logs/access_log" combined
    ErrorLog "/home/ubuntu/www/logs/error_log"
    DocumentRoot "/home/ubuntu/www/docs"
    WSGIScriptAlias /wsgi/test /home/ubuntu/www/wsgi/test.py
</virtualhost>

LoadModuleでさきほど一般ユーザ配下に置いたmod_wsgi.soを読み込み、デーモンモードにするのでDaemonProcessを指定する。
一般ユーザーでpip3モジュールを入れているので、その置き場をWSGIPythonPathディレクティブで指定する。それは、

python3 -c 'import sys; print(sys.path)'

などと打つと、確認できる。

さきほど作った実行ディレクトリで、docsにはhtmlやimageなどの静的ファイルを置くことを想定。

WSGIScriptAliasディレクティブで、実行したいpythonスクリプトのファイルを指定する。上記例では、

http://127.0.0.1/wsgi/test

とブラウザアクセスすると、/home/ubuntu/www/wsgi/test.pyが実行される。

Apache2コンフィグファイルの有効化

最初からある000-default.confへのシンボリックリンクを削除して、wsgi-server.confへのリンクを貼り直す。

sudo -s
cd /etc/apache2/sites-enabled
rm 000-default.conf
ln -s ../sites-available/wsgi-server.conf

これでwsgi-server.confが読み込まれる。

Apache2コンフィグファイルのチェックと再起動

sudo apache2ctl configtest
Syntax OK

エラーが出なければOK、再起動する。念のためstart/stopしている。

sudo /etc/init.d/apache2 stop
sudo /etc/init.d/apache2 start

mod_wsgiつきApache2の起動確認

sudo cat /var/log/apache2/error.log

[Fri Jul 14 15:05:46.360054 2023] [mpm_event:notice] [pid 46126:tid 140076424537984] AH00489: Apache/2.4.52 (Ubuntu) mod_wsgi/4.9.4 Python/3.10 configured -- resuming normal operations

実行ディレクトリにログが作成されているかも確認。

ls /home/ubuntu/www/logs

access_log  error_log

テストスクリプトtest.pyの作成

「こんにちは」とだけ出力するシンプルなもの。

/home/ubuntu/www/wsgi/test.py

#-*- coding: utf-8 -*-
def wsgi_app(environ, start_response):
    import sys
    output = 'こんにちは'.encode('utf8')
    status = '200 OK'
    headers = [('Content-type', 'text/plain; charset=UTF-8'), ('Content-Length', str(len(output)))]
    start_response(status, headers)
    yield output

# mod_wsgi need the *application* variable to serve our small app
application = wsgi_app

UTF-8N/LFで保存する。

ブラウザからアクセスして確認

http://127.0.0.1/wsgi/test

と打って、「こんにちは」と出ればOK。access_log, error_logも確認しておく。

なお、こんにちはをさようならなどと変えて再アクセスしたらちゃんと変わるはず。デーモンモードなのでApache再起動の必要はない。

しかしながら、異常に遅い。何か設定が悪いのか。。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

【キーワード検索】