Flask + mod_wsgi + ApacheをmacOSに環境構築


## 背景
### 個人：
FlaskアプリをMacOSのApacheで動作させたいですが、apacheに関する知識がほぼゼロです。

### 必要性: 
最近のmacosのアップデートで安全性が向上したと同時に、環境構築もややこしくなりました。昔の記事が通用できないところが多くて、自分の経験を共有する必要があると思います。

### 実行環境：
Apache -> 2.4.54
Python -> 3.10.11
pip3 -> 23.1.2
flask -> 2.3.2

```
>httpd -v
Server version: Apache/2.4.54 (Unix)
...

> python3
Python 3.10.11 (main, May 29 2023, 06:42:58) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
...

> pip3 --version
pip 23.1.2 from /Users/rikanshin/.local/lib/python3.10/site-packages/pip (python 3.10)

> pip3 show flask
Name: Flask
Version: 2.3.2
...
```

ps:他の記事によるとMacOSのデフォルトのpython3があまりよくないそうです。
https://www.python.org/downloads/macos/
上からダウンロードしてインストールしてください。

pythonをインストールしたらパスを通る

できたらpip3の場所をチェック
```
which pip3
```
場所が変わったらOKです。

## 背景知識
FlaskはPythonのWebフレームワークの一つで、PythonのアプリをApacheで動作させたい場合wsgiが必要です。しかし、wsgiは自分でダウンロードしてApacheにロードしなければなりません。それに、Flaskアプリのファイル以外、自作のwsgiファイルが必要です。

## 最終目標
localhost:80で **Hello, Apache!** を表示します

## 構築過程
### 1.mod_wsgiをインストール
最新版のMacOSはPython3とhttpd(apachectl)とpip3がインストール済みです。

まずflaskがあるかどうかをチェック
```
pip3 show flask
```
もしなければインストールする
```
pip3 install flask
```

そして、mod_wsgiをダウンロード
```
pip3 install mod_wsgi
```
**エラー**があるはずです。
```
$ pip3 install mod_wsgi
Collecting mod_wsgi
  Using cached mod_wsgi-4.9.4.tar.gz (497 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [17 lines of output]
      Traceback (most recent call last):
  ...
```
それはXcode command line toolsがなくてコンパイルできないからです。
そこで、**App Store**で**Xcode**を**ダウンロードしてから**
```
xcode-select --install
```
というコマンドでインストールしてください。(おすすめ)

もしXcodeが重くてダウンロードしたくない場合
https://style.potepan.com/articles/9093.html#XcodeCommand_Line_Tools
あるいは
https://qiita.com/SayCheeese/items/1b9db660917049bbad64
を参照してください。

Command Line Toolsをインストールしたら,mod_wsgiをインストールします。

```
pip3 install mod_wsgi
```

できたらmod_wsgiの位置を調べます
```
> pip3 show mod_wsgi
Name: mod-wsgi
Version: 4.9.4
Summary: Installer for Apache/mod_wsgi.
Home-page: https://www.modwsgi.org/
Author: Graham Dumpleton
Author-email: Graham.Dumpleton@gmail.com
License: Apache License, Version 2.0
Location: /Users/rikanshin/.local/lib/python3.10/site-packages
Requires: 
Required-by: 
```
そこのLocationは目的地です。
自分の出力のLocationに従って移動して、そこのmod_wsgiフォルダのserverフォルダに移動したら、「mod_wsgi-py310.cpython-310-darwin.so」のようなファイルがあるはずです。ファイル名のcpython-310はpython3.10バージョンならOKという意味で、自分のpythonバージョンが合ってるかどうかをチェックしてください。

### テストファイルの用意
まずフォルダを作ります。(ここは例として /Users/rikanshin/Desktop/flask/myapp とします)
そこで三つのファイルを作ります

1.hello.py(flaskアプリファイル)
```
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello, Apache!'

if __name__ == '__main__':
    app.run()

```

2.test1.py(wsgiテストファイル)
```
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]
```

3.test.wsgi(hello.pyのためのwsgiファイル)
```
import sys
sys.path.insert(0, '/Users/rikanshin/Desktop/flask/myapp')

from hello import app
application = app
```
そこのpathを適宜に変えてください。
さらに三つのファイルに実行権限を与えます。
```
chmod 755 ファイル名
```

それでファイルの用意がOKです。

### mod_wsgiをapacheに配置
まず、apacheの設定ファイル(デフォルトは /etc/apache2/httpd.conf)の最後に
```
<VirtualHost *:80>
    LoadModule wsgi_module /Users/rikanshin/.local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-darwin.so
    WSGIScriptAlias / /Users/rikanshin/Desktop/flask/myapp/test.wsgi
    <Directory /Users/rikanshin/Desktop/flask/myapp>
        Require all granted
    </Directory>
</VirtualHost>
```
書いてください

LoadModule wsgi_moduleの後ろは先ダウンロードした .so ファイルのパスを記入してください
WSGIScriptAlias / の後ろにwsgiファイルのパスを記入してください
(まずはtest1.py、通ったらtest.wsgiに書き換えてください)
<Directory>の中に先ほど作ったフォルダのパスを記入してください

保存したら、httpdファイルをチェックします。
```
apachectl -t
```
多分エラーが出ます。
```
[so:error] [pid 3908] AH06665: No code signing authority for module at...
```
それはコード署名証明書がないらしいです。
そこで以下のURLに従って
https://pointsandlines.jp/server-side/php/code-signing-in-macos-monterey
モジュールの有効化を行ってください。

### 権限なしのテスト
まずサーバを立ち上げます
```
sudo apachectl start
```
そしてブラウザで http://localhost:80
を開きます
多分Internal Server Errorが出てきます。
その時error_logをチェック(デフォルトは /var/log/apache2/error_log)
もし以下のような記録があったら、httpdは実行権限がないことがわかります。
```
[wsgi:error] [pid 7827] (1)Operation not permitted: [client ::1:52854] mod_wsgi (pid=7827, process='', application='rikanshinnoMacBook-Pro.local|'): Could not read/compile source file ...
```
そこでhttpdにフルディスクアクセスの権限に与えます。
まずhttpdの位置を探します。
```
$ which httpd
/usr/sbin/httpd
```
そして、macbookのシステム設定-->プライバシーとセキュリティ-->フルディスクアクセスに移動してください。一番下の 「＋」を押して、パスワードを入力して、finderが開かれたはずです。その後command+shift+gを押したら、先のhttpdのパスを入力して、右下の「開く」を押します。
最後は以下のようになったらOKです。
![スクリーンショット 2023-06-05 1.30.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2848485/acbbd496-9560-dee9-f6bf-a527edcd4189.png)


### 最終テスト
最後はapacheを再起動して
```
sudo apache restart
```
そしてブラウザで http://localhost:80
を開きます
WSGIScriptAlias / /Users/rikanshin/Desktop/flask/myapp/test1.py
の場合、Hello Worldが表示します。それはwsgiモジュールが正しく動作していることを示しています。
WSGIScriptAlias / /Users/rikanshin/Desktop/flask/myapp/test.wsgi
の場合、Hello,Apache!が表示します。それはwsgiモジュールとpythonとflaskが全部正しく動作していることを示しています。

### 最後
お疲れ様でした。
長く書きましたが、参考になれば嬉しいです。
初心者なのでどこが間違っていたら指摘してください!