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で保存する。
ブラウザからアクセスして確認
と打って、「こんにちは」と出ればOK。access_log, error_logも確認しておく。
なお、こんにちはをさようならなどと変えて再アクセスしたらちゃんと変わるはず。デーモンモードなのでApache再起動の必要はない。
しかしながら、異常に遅い。何か設定が悪いのか。。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
Windows版Google Driveが使用中と言われアンインストールできない場合
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
【Apache】サーバーに同時接続可能なクライアント数を調整する
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合
【Linux】iconv/libiconvをソースコードからインストール
Ubuntu Server 21.10でイーサリアムブロックチェーン【その5】