一方、最近のWebアプリは、クライアントからもサーバへ情報を送信しつつ、サーバとクライアントが
連携して機能しています。このため、この種のWebアプリを動かすには、
従来のWebサーバ
(httpサーバ) だけでは不十分です。
Flask, FastAPI, Django, Dashなどは、pythonでインタラクティブなWebアプリを作成できる
Webフレームワークですが、上記の理由のため、WSGI (Web Server Gateway Interface) という、
pythonのWebアプリケーションとWebサーバー間のインターフェースを利用しています。
以下の例では、多くの場合にWSGIプログラムの起動プログラムとしてapp.pyという、同一の名前を使っています。
pythonの仮想環境 dash を共有しているため、sys.path
が共有されてしまい、想定しているのとは異なるapp.pyを
読み込むことがあるようで、httpdの再起動ごとにことなる挙動をしています。
これを回避するには、pythonの仮想環境を別々に作るか、sys.pathに入れたディレクトリのスクリプト名を
すべて変える必要がありそうです。実際には、app.pyを、[Application
Name]_app.py のようにして名前が
被らないようにするのが無難そうです。
この修正はおいおい進めていきますが、plotly-Dash-Flaskプログラム のプログラムでは、期待したものとは異なるプログラムが起動されることがありますが、ご容赦ください。
上記のように、Webフレームワークを用いたpythonプログラムを
Webサーバ上で稼働させる (Deploy: デプロイと呼びます) ためには、
WSGIあるいは同等の機能をインストールする必要があります。
本ページでは、AlmaLinux9のapache2にmod_wsgiをインストールする方法を説明します。
mod_wsgiでは、WSGIScriptAlias の設定に対応するURIでアクセスがあった場合、
mod_wsgiにより*.wsgiファイルが起動されます。
そのため、以下の流れでインストール、設定を行います
インストール:
アプリごとの設定:
接続:
使用しているpythonモジュール:
% pip uninstall dash dash-core-components dash-html-components dash-table -y
% pip install flask dash Werkzeug
で最新版をインストール。本ページ作成時のバージョンは以下の通り
(dash) [root@usrv1 test1]# pip list | grep -E "dash|Flask|Werkzeug"
dash 2.9.3
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-table 5.0.0
Flask 3.1.0
Flask-Bcrypt 1.0.1
Flask-Compress 1.17
Flask-DebugToolbar 0.16.0
Flask-Login 0.6.3
Flask-SQLAlchemy 3.1.1
Werkzeug 3.1.3
アプリ群のhome: /home/conf/app
注: セキュリティの観点から、httpdでアクセスできない (documnet_root以下以外)
パスが望ましい
ただし、本Webでソースを公開しているアプリは
/D2MatE/web/wsgi 以下に作っている
python仮想環境: /home/conf/dash
注: セキュリティの観点から、httpdでアクセスできない (documnet_root以下以外)
パスに作る
% sudo dnf install python3 -y
% sudo dnf install python3-devel -y
% sudo dnf install python3-pip -y
仮想環境を作った方がいい
・ apacheがpython、site_packagesにアクセスできる必要がある
・ dashの場合、apacheがdashに含まれるReactへアクセスできるようにする必要がある
本Webの場合、仮想環境はアプリケーションルートの下に作っている
% cd /home/conf/app # WSGIアプリケーションルート
% python -m venv dash # 仮想環境home
仮想環境のpythonのhome: /home/conf/app/dash
仮想環境のライブラリ: /home/conf/app/dash/lib/python3.11
% source ./dash/bin/activate
* /etc/httpd/conf/httpd.conf か、/etc/httpd/conf.d/wsgi.conf に以下の設定を入れる
WSGIPythonHome: 共通のpythonの実行ファイルパスのhome
python-home:
アプリごとのpythonのhome。例えば実行ファイルが/usr/bin/python3.11であれば、/usr
WSGIPythonPath: pythonモジュールパス
WSGIScriptAlias: 設定ファイルcalendar.wsgiへのパスと、別名
WSGIDaemonProcess: アプリごとの設定。
python-home:
pythonのhome。仮想環境を使うならそのディレクトリ、使わない場合は省略してもよい
python-path: pythonモジュールのパス
WSGIProcessGroup: アプリ固有の名前
WSGIPythonHome /home/conf/app/dash
WSGIPythonPath /home/conf/app/dash/lib/python3.11:/home/conf/app/dash/lib/python3.11/site-packages
<VirtualHost *:80>
ServerAdmin kamiya.t.aa@m.titech.ac.jp
ServerName d2mate.mdxes.iir.isct.ac.jp
DocumentRoot /home/conf/public_html
ErrorLog logs/d2mate-error_log
CustomLog logs/d2mate-access_log common
ScriptAlias /cgi-bin/ "/home/conf/public_html/cgi-bin/"
# アプリケーション1: calendar
WSGIScriptAlias /calendar /home/conf/app/calendar/calendar.wsgi
WSGIDaemonProcess calendar python-home=/home/conf/app/dash
python-path=/home/conf/app/dash/lib/python3.11:/home/conf/app/calendar
WSGIProcessGroup calendar
# アプリケーション2: chat
WSGIScriptAlias /chat /home/conf/app/chat/chat.wsgi
WSGIDaemonProcess chat python-home=/home/conf/app/dash
python-path=/home/conf/app/dash/lib/python3.11:/home/conf/app/chat
WSGIProcessGroup chat
# アプリケーション3: fileTree
WSGIScriptAlias /fileTree /home/conf/app/fileTree/fileTree.wsgi
WSGIDaemonProcess fileTree python-home=/home/conf/app/dash python-path=/home/conf/app/dash/lib/python3.11:/home/conf/app/fileTree
WSGIProcessGroup fileTree
# Dashアプリケーション
WSGIScriptAlias /test1 /home/conf/app/test1/test1.wsgi
WSGIDaemonProcess test1 python-home=/home/conf/app/dash python-path=/home/conf/app/dash/lib/python3.11:/home/conf/app/test1
WSGIProcessGroup test1
WSGIApplicationGroup %{GLOBAL}
<Directory /home/conf/app/test1>
Require all granted
</Directory>
<Directory /home/conf/app/test1/assets>
Require all granted
</Directory>
<Directory /home/conf/app/calendar>
Require all granted
</Directory>
<Directory /home/conf/app/chat>
Require all granted
</Directory>
<Directory /home/conf/app/fileTree>
Require all granted
</Directory>
</VirtualHost>
Dashアプリの場合、WSGIScriptAlias
のルーティング先を、pythonスクリプトにも教える必要があるので、確認すること。
templateも対応する必要があるので、Flask
vs Dashページを参照
WSGIScriptAlias /test1 /home/conf/app/test1/test1.wsgi の場合:
url_base = '/test1/'
app = dash.Dash(__name__,
requests_pathname_prefix = url_base,
serve_locally =
True,
)
server = app.server
必要に応じて以下も追加:
url_base_pathname = '/test1/', (多分いらない)
assets_folder= '/home/conf/app/test1/assets',
(assetsで404エラーが出たら追加)
* calendar.wsgi (Flaskの場合) の例:
import sys
sys.path.insert(0, '/home/conf/app/calendar/calendar.wsgi')
from calendar import app as application
import アプリケーション起動pythonスクリプトのファイル名 import applicationのインスタンス変数名 as application
Dashの場合、applicationのインスタンス変数名は app.server (で取得できるFlaskオブジェクトなど) を指定する
$ sudo systemctl restart httpd
エラーが出た場合はstatusを確認することでエラー原因を特定する
$ sudo systemctl status httpd
Flask, Dashアプリ内でprint()で出力した内容はerror_logに出力される
<VirtualHost *:80>
ServerName app1.example.com
WSGIScriptAlias / /home/conf/app/app1/app1.wsgi
WSGIDaemonProcess app1 python-path=/home/conf/app/app1
WSGIProcessGroup app1
<Directory /home/conf/app/app1>
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName app2.example.com
WSGIScriptAlias / /home/conf/app/app2/app2.wsgi
WSGIDaemonProcess app2 python-path=/home/conf/app/app2
WSGIProcessGroup app2
<Directory /home/conf/app/app2>
Require all granted
</Directory>
</VirtualHost>
* アクセス方法
virtual hostを利用
app1:http://app1.example.com
app2:http://app2.example.com
WSGIScriptAliasを利用
app1: http://your_server_ip_or_domain/app1
app2:http://your_server_ip_or_domain/app2
参考: https://qiita.com/Nats72/items/fd83bfea047a615ad3a2
% pip install gunicorn
% gunicorn -w 4 -b 0.0.0.0:8050 app:app
Webサーバ起動中に常時Webアプリを使えるようにするためには、Linuxでは
daemon化 (サービス化) するのが一般的です。
以下に、Redhut系 (AlmaLinuxなど) での一般的なdaemon化について説明します。