【 「Pythonの仮想環境 venv と virtualenvのもっとも大きな違い 」 】
その後、調べるにつけ、Pythonアプリはvirtualenv環境下で動かすべき、という記事を沢山見つけましたので、やってみます。
Virtualenv環境に
・CentOS 7 に標準のPython 2.7 とは別のバージョン(Python 3.7)をインストール。
・Apache(httpd 2.4)のVirtual Hostは、mod_wsgi開発者のGraham Dumpletonさんが強く推奨する
Daemon Mode (デーモン・モード)で記述。
・wsgiスクリプトには、virtualenvを自動起動する為の activate_this.py をinvokeする設定を入れます。
途中で解説を入れながら、ステップ・バイ・ステップで、1つずやります。
1. ディレクトリ・ファイル構成
virtualenvでは、仮想環境構築用のディレクトリとPythonアプリ(今回はflask)は、別ディレクトリに作成することが推奨されていますので、それに準拠します。
vitualenv を走らせるには、2つのファイルを記述する事がポイントになります。
・ httpdのconf ファイルに<virtual host>の記述
・ wsgiスクリプト
(仮想環境構築)
/home/virtual_test
|
|---virtual_test_child <-- 仮想化する対象のディレクトリーです。
|
|----- bin <-- activate_this.pyは、ここに自動生成されます。
|-----
(Flaskアプリ)
/var/www/html/virtual_test_app
|-----app.wsgi
|-----app.py
|----- templates
|---sample01.html
|---sample02.html
では、やってみます。
1. 仮想環境の構築
[@ home]# mkdir virtual_test
[@ home]# cd virtual_test
[@ virtual_test]# mkdir virtual_test_child
[@ virtual_test]# virtualenv virtual_test_child
Using base prefix '/usr/local'
New python executable in /home/virtual_test/virtual_test_child/bin/python3
Also creating executable in /home/virtual_test/virtual_test_child/bin/python
Installing setuptools, pip, wheel...
done.
(virtual_test_child) [@ virtual_test]# python -V
Python 3.6.8
(virtual_test_child) [@ virtual_test]# which python
/home/virtual_test/virtual_test_child/bin/python <-- されます。
(virtual_test_child) [@ virtual_test]# pip freeze
(virtual_test_child) [@ virtual_test]#
2. Pythonのインストール
1)ツールのインストール
(virtual_test_child) [@ virtual_test]# yum groupinstall "development tools"
(エラー表示)
Maybe run: yum groups mark install (see man yum)
No packages in any requested group available to install or update
(対処):epel が上手く機能していない可能性があるため
(virtual_test_child) [@ virtual_test]# yum clean all
(virtual_test_child) [@ virtual_test]# yum --disablerepo=\* --enablerepo=base,updates groupinstall "Development Tools"
(同じエラー表示)
Maybe run: yum groups mark install (see man yum)
No packages in any requested group available to install or update
(確認)
(virtual_test_child) [@ virtual_test]# yum grouplist
Installed Groups:
Development Tools
うーむ。 グローバルなものが参照されちゃうんですね。
(以上、エラー対処は、2015/12/11
https://www.centos.org/forums/viewtopic.php?t=55400 を参照しました。)
#yum list installed で確認すると、必要なツールは全て、インストールされている表示になって
しまいます。
なので、これ以上、virtualenv環境でのツールのインストールはしません。
初めて、Pythonをソース・コードからインストールされる方は、こちらも参考にしてみてください。
必要なパッケージをインストールしています。
【 「これで動く (1) !! WebArena VPS(CentOS7)でFlaskを動かす 」 】
virtual_test_child) [@ virtual_test]# wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
2019-01-09 20:48:59 (10.8 MB/s) - ‘Python-3.7.2.tgz’ saved
(virtual_test_child) [@ virtual_test]# ls -a
. .. Python-3.7.2.tgz virtual_test_child
(virtual_test_child) [@ virtual_test]# tar zxvf Python-3.7.2.tgz
(virtual_test_child) [@ virtual_test]# ls -a
. .. Python-3.7.2 Python-3.7.2.tgz virtual_test_child
(virtual_test_child) [@ virtual_test]# cd Python-3.7.2
(virtual_test_child) [@ Python-3.7.2]# ./configure --enable-shared
(virtual_test_child) [@ Python-3.7.2]# ./configure --enable-optimizations
(virtual_test_child) [@ Python-3.7.2]# make && make altinstall
(error)
ModuleNotFoundError: No module named '_ctypes'
凄く時間がかかって、この結果はがっかりします。
原因は、 libffi-develがインストールされていないから。
(https://bugs.python.org/issue31652)
(virtual_test_child) [@ Python-3.7.2]# yum install libffi-devel
の前に、
以下のdependenciesがインストールされているか確認。
(virtual_test_child) [@ Python-3.7.2]# yum list installed | grep -ie httpd-devel -e python-deve
l
httpd-devel.x86_64 2.4.6-88.el7.centos @base
python-devel.x86_64 2.7.5-76.el7 @base
インストールされていますね。
では、
(virtual_test_child) [@ Python-3.7.2]# yum install libffi-devel
Complete!
もう一回、最適化とコンパイル。
(virtual_test_child) [@ Python-3.7.2]# ./configure --enable-optimizations
(virtual_test_child) [@ Python-3.7.2]# make && make altinstall
Installing collected packages: setuptools, pip
Successfully installed pip-18.1 setuptools-40.6.2
無事にpythonがインストールされました。
3. mod_wsgiをインストールする
(virtual_test_child) [@ Python-3.7.2]# cd .. <- pythonをインストールしたdirectoryに戻る
(virtual_test_child) [@ virtual_test]#wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.6.tar.gz
2019-01-10 01:34:34 (932 KB/s) - ‘4.5.6.tar.gz’ saved
(virtual_test_child) [@ virtual_test]# ls -a
. .. 4.5.6.tar.gz Python-3.7.2 Python-3.7.2.tgz virtual_test_child
(virtual_test_child) [@ virtual_test]# tar zxvf 4.5.6.tar.gz
(virtual_test_child) [@ virtual_test]# which python3
/home/virtual_test/virtual_test_child/bin/python3
(virtual_test_child) [@ virtual_test]# deactivate
[@ virtual_test]# cd /
[@ /]# find -name apxs
./usr/bin/apxs
[@ /]# cd /home
[@ home]# ls -a
. .. virtual_test
[@ home]# cd virtual_test
[@ virtual_test]# ls -a
. 4.5.6.tar.gz Python-3.7.2 virtual_test_child
.. mod_wsgi-4.5.6 Python-3.7.2.tgz
[@ virtual_test]# source virtual_test_child/bin/activate
(virtual_test_child) [@ virtual_test]# cd mod_wsgi-4.5.6
(virtual_test_child) [@ mod_wsgi-4.5.6]# ./configure --with-apxs=/usr/bin/apxs --with-python=/usr/bin/python3
configure: creating ./config.status
config.status: creating Makefile
(virtual_test_child) [@ mod_wsgi-4.5.6]# make && make install
Libraries have been installed in:
/usr/lib64/httpd/modules
chmod 755 /usr/lib64/httpd/modules/mod_wsgi.so <-後でmod_wsgi.soが、pythonのshared libraryを使えているか確認します。
4. Flaskをインストールする
(virtual_test_child) [@ mod_wsgi-4.5.6]# python3 -m pip install flask==
Collecting flask==
(virtual_test_child) [@ mod_wsgi-4.5.6]# pip install flask==1.0.2
Successfully installed Jinja2-2.10 MarkupSafe-1.1.0 Werkzeug-0.14.1 click-7.0 flask-1.0.2 itsdangerous-1.1.0
必要な環境構築が終わりましたので、各ファイルを置いていきます。
ファイル名:venv_mossymob.tk.conf
設置場所:/etc/httpd/conf.d
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
<VirtualHost *:80>
ServerName mossymob.tk
WSGIDaemonProcess virtual_test_app user=apache group=apache python-home=/home/virtual_test/virtual_test_child
WSGIScriptAlias /virtual_test_app /var/www/html/virtual_test_app/app.wsgi
<Directory /var/www/html/virtual_test_app>
WSGIProcessGroup virtual_test_app
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
CustomLog /home/virtual_test/access.log common
ErrorLog /home/virtual_test/error.log
LogLevel info
</VirtualHost>
① WSGIDaemonProcessへの python-home オプションの指定
(公式: https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html)
Embeded ModeやDaemon Modeで1つのアプリケーションを1つのデーモン・グループで使用する場合など、多くの場合、以下のpython-home オプションを、WSGIDaemonProcessに、使用するpythonのルート・ディレクトリを明記してあげれば、この1行だけの追加でVirtualenv に対応できるようになるそうです。
WSGIDaemonProcess myapp python-home=/usr/local/venvs/myapps
Virtualenvで使用するpythonのパスは、
which python や python -c 'import sys; print(sys.prefix)' で、確認できます。
今回は、virtualenv のディレクトリにPythonをインストールしていますので、
(virtual_test_child) [virtual_test]# which python
/home/virtual_test/virtual_test_child/bin/python
(virtual_test_child) [ virtual_test]# python -c 'import sys; print(sys.prefix)'
/home/virtual_test/virtual_test_child
なので、 python-home=/home/virtual_test/virtual_test_child をWSGIDaemon Process で
指定しています。
ファイル名:app.wsgi
設置場所:/var/www/html/virtual_test_app
# coding: utf-8
activate_this ='/home/virtual_test/virtual_test_child/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
import sys
sys.path.insert(0, '/var/www/html/virtual_test_app')
from app import app as application
*activate_this.pyは、virtualenvを作成した際に、binディレクトリ内に自動で生成されています。activate_this ='/home/virtual_test/virtual_test_child/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
import sys
sys.path.insert(0, '/var/www/html/virtual_test_app')
from app import app as application
ファイル名:app.py
設置場所:/var/www/html/virtual_test_app
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
message="Hi, there!"
return render_template("sample01.html", message=message)
@app.route('/add',methods=['POST'])
def add():
if request.method =='POST':
result = request.form['new_num']
return render_template("sample02.html", result=result)
if __name__ == '__main__':
app.run()
app = Flask(__name__)
@app.route('/')
def index():
message="Hi, there!"
return render_template("sample01.html", message=message)
@app.route('/add',methods=['POST'])
def add():
if request.method =='POST':
result = request.form['new_num']
return render_template("sample02.html", result=result)
if __name__ == '__main__':
app.run()
ファイル名: sample01.html
設置場所:/var/www/html/virtual_test_app/templates
<html>
<head>
<meta charset="utf-8">
</head>
<body>
{{message}}
<form action="/virtual_test_app/add" method="post">
<p>Input the number you like:</p>
<input type="text" name="new_num" >
<input type="submit" value="Do">
</form>
</body>
</html>
*form actionの参照ディレクトリの記述は気をつけましょう。<head>
<meta charset="utf-8">
</head>
<body>
{{message}}
<form action="/virtual_test_app/add" method="post">
<p>Input the number you like:</p>
<input type="text" name="new_num" >
<input type="submit" value="Do">
</form>
</body>
</html>
*sample02.htmlは、resultを表示しているだけですし、今まで多く書いてきていますので
今回は記述を省略します。
これで、http:mossymob.tk/virtual_test_app にブラウザでアクセスすると、
無事に値がsample01.htmlからsample02に引き渡されて、
ルーティングもできることが確認できました。
* mod_wsgi が、シェアード・ライブラリを使用できているかの確認。
(シェアド・ライブラリを使えていなくてもmod_wsgiは動きますが、メモリーを大量に消費してい
思わぬ問題を引き起こす可能性があるそうです。)
上でmod_wsgi.soが格納されたdirectoryがありましたが、そこで、以下の ’ldd’ コマンドを実行。
# cd /usr/lib64/httpd/modules/
[ modules]# ldd mod_wsgi.so
linux-vdso.so.1 => (0x00007ffe424ed000)
libpython3.6m.so.1.0 => /lib64/libpython3.6m.so.1.0 (0x00007f6138849000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f613862d000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f6138428000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f6138225000)
libm.so.6 => /lib64/libm.so.6 (0x00007f6137f23000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6137b55000)
/lib64/ld-linux-x86-64.so.2 (0x000055a55f838000)
以上のようなリストが表示されていれば大丈夫。
これで、お終いです。
参考)
mod_wsgiのモード別の<Virtual Host>の記述方法(公式)
https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
(後日再挑戦)
◇virtual host
LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
<VirtualHost *:80>
ServerName uslife.mossymob.tk
DocumentRoot /var/uslife/html
<Directory /var/uslife/html>
Require all granted
</Directory>
WSGIDaemonProcess forum user=apache group=apache python-home=/home/venv_env/python37
WSGIScriptAlias /app/forum /var/uslife/html/app/forum/app.wsgi
<Directory /var/uslife/html/app/forum>
WSGIProcessGroup forum
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
CustomLog /home/venv_env/access.log common
ErrorLog /home/venv_env/error.log
LogLevel info
</VirtualHost>
◇ app.py
from flask import Flask,render_template,request
app = Flask(__name__)
@app.route('/')
def index():
message="Hi, there!"
return render_template("sample01.html", message=message)
@app.route('/add',methods=['POST'])
def add():
if request.method =='POST':
result = request.form['new_num']
#else:
# result = "No wish! Ah?"
return render_template("sample02.html", result=result)
if __name__ == '__main__':
app.run()
◇html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
{{message}}
<form action="/add" method="post">
<p>Input the number you like:</p>
<input type="text" name="new_num" >
<input type="submit" value="Do">
</form>
</body>
</html>
これで動く。 まだ、ルーティングの記述方法が良く理解できていないようだ。
sample01.html
http://uslife.mossymob.tk/app/forum/
sample02.html
http://uslife.mossymob.tk/app/forum/add
0 件のコメント:
コメントを投稿