LoginSignup
0
0

Apache2でwsgiを使ってvenv上のFlaskを動かす

Last updated at Posted at 2024-03-26

始めに

Ubuntu上のApache2でmod_wsgiを利用してFlaskのwebアプリを動かす方法を記述する。
Pythonはpyenvとvenvを利用した仮想環境を使う。

上記の構成でWEBサーバーを構築しようとしたところ、多くのエラーに見舞われ、たくさんの記事を読んだり、一つひとつ設定を試すことになったため、自分が利用した情報とわかったことをまとめた。

前提条件

Apacheの設定、Flaskのプログラム作成やpyenvとvenvによる環境構築は終わっているものとする。
python app.pyなどでローカルサーバーを動かせる状態にあればよい。

筆者の環境

OS : Ubuntu 22.04 (VPS上)
Pyhton : 3.11.6 (pyenv+venv)

ディレクトリ構成(抜粋)
root/
  ├ etc/
    └ apache2/
      ├ sites-available/
        └ example.com.conf
        └ example.com-le-ssl.conf
      └ sites-enabled/
        └ example.com.conf
        └ example.com-le-ssl.conf
  └ var/
    └ www/
      └ example.com/
        ├ html/
        └ wsgi-bin/
          ├ app.py
          ├ index.wsgi
          └ venv/
            ├ bin/
            └ lib/
              └ pyhton3.11/
                └ site-packages/
                  └ mod_wsgi/
                    └ server/
                      └ mod_wsgi-py311.cpython-311-x86_64-linux-gnu.so

mod_wsigのインストール

Apacheでwsgiを使うためのモジュールmod_wsigをインストールする。
今回はデーモンモードを使う。(違いについてはこの記事が詳しい。)
本番環境で使用するvenvの仮想環境に入った上で、下記コマンドを実行する。

pip install mod-wsgi

この時点でapache2-dev を apt などでインストールしてないとエラーになる。
(インストール方法:apt install apache2-dev)

mod_wsgiをaptよりインストールする方法もあるが、pyenvとvenv を使う場合はapt install libapache2-mod-wsgi-py3でインストールすると、ライブラリの読み込み時などにエラーが発生した。
この記事によると、aptでのインストール時に使うPythonとアプリを動かすPythonのバージョンが異なるため、エラーになるらしい。

Apache の設定

/etc/apache2/sites-available/あたりにあるVirtualHostの設定ファイルを編集する。

example.com.conf
<VirtualHost *:80>
	ServerName example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/example.com/html

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

# ここから記入
	LoadModule wsgi_module /var/www/example.com/wsgi-bin/venv/lib/python3.11/site-packages/mod_wsgi/server/mod_wsgi-py311.cpython-311-x86_64-linux-gnu.so
	WSGIDaemonProcess app user=www-data  group=www-data threads=5 python-home=/var/www/example.com/wsgi-bin/venv python-path=/var/www/example.com/wsgi-bin/venv/lib/python3.11/site-packages
	WSGIScriptAlias / /var/www/example.com/wsgi-bin/index.wsgi
	<Directory "/var/www/example.com/wsgi-bin/">
		WSGIProcessGroup app
		WSGIApplicationGroup %{GLOBAL}
		WSGIScriptReloading On
		Order allow,deny
		Allow from all
		#.htaccessの有効化(無くてもよい)
		AllowOverride All
	</Directory>
# ここまで記入

	RewriteEngine on
	RewriteCond %{SERVER_NAME} =example.com
	RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

LoadModule

LoadModuleで、venvの中の/lib/python3.11/site-packages/mod_wsgi/server/mod_wsgi-py311.cpython-311-x86_64-linux-gnu.soを指定することで、pipによってインストールしたmod_wsgiを読み込んでいる。

WSGIDaemonProcess

WSGIDaemonProcessとWSGIProcessGroupのappの部分は任意の名前でいいが、同じにしないといけない。
また、VirtualHostなどで複数のWSGIDaemonを動かす場合は、互いに重複しないようにする。

userとgroupはpythonを実行するユーザーとグループの名前にする。(www-dataはApacheなどが利用するもの)

python-homeはvenvのディレクトリを指定する。
venv/bin/ではなくvenv/を指定しないといけないので注意。

python-pathにはライブラリのあるディレクトリを指定する。
ここに書く代わりに、wsgiファイルのsys.pathに書く方法もある。(index.wsgiのコメントアウト部参照)

SSLを使う場合は、同様の内容をexample.com-le-ssl.confなどに書くと思うが、SSLの方にはWSGIDaemonProcessを書いてはいけない。
Let's encryptなどでは自動でコピーされるので、この部分だけ消す必要がある。
また、LoadModuleもSSL用のファイルでは不要である。

WSGIScriptAlias

cgiで使うAliasと同じ書き方をする。
今回はexample.comへアクセスすればFlaskに繋がるようにしている。
WSGIScriptAlias /wsgi/ /var/www/example.com/wsgi-bin/index.wsgiと書けば、example.com/wsgi/にアクセスすることでFlaskへ繋がるようにできる。
詳細はこの記事が詳しい。

wsgiファイル

index.wsgi
import sys

sys.path.insert(0, "/var/www/example.com/wsgi-bin")
# sys.path.insert(0, "/var/www/example.com/wsgi-bin/venv/lib/python3.11/site-packages")

from app import app as application

sys.path.insertでpythonプログラムが置かれているディレクトリを指定し、importできるようにする。

コメントアウトしている部分は、ライブラリのディレクトリをwsgiファイルで指定する場合である。

最後に

これでsystemctl restart apache2.serviceをすれば完了である。

mod_wsigをデーモンモードで動かしているため、Flaskのプログラムを更新したらApache2をリスタートしなくても変更が反映されるという情報を得たが、自分の環境では再現できなかった。

参考にさせていただいたサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0