Apache To Python For mod_wsgi

#Apache To Python For mod_wsgi
## まずはじめに知っててほしいこと
Apache上でpythonを動作させる場合、cgiとして単体で動かすことは可能だが、
[Bottle][]や[Django][]などのフレームワーク上で動作させる際には、下記の外部module(mod_wsgi)が必要となる。
今回は、[Bottle][]を前提に設定を進めて行きます。
[Django][]は、まだ試していない為、別途設定が異なることがあるかと思います。
公式サイトなどを参考にご対応ください。

※macOSHighSierraでの動作しています。

## 構築環境
iMacのみのスペックを記載してますが、同様な環境構築にて、
MacBook PRO,Mac miniでも動作している事を確認済みです。

```md:iMac(Retina-5K,27-inch,2017)
バージョン 10.13.2
プロセッサー 4.2 GHz Intel Core i7
メモリ 64 GB 2400 MHz DDR4
グラフィック Radeon Pro 580 8 GB
```

## mod_wsgiの存在 [引用元: [wikipedia][wsgi]]
### [wsgi(Web Server Gateway Interface)][wsgi]

#### Web Server Gateway Interfaceとは...
Web Server Gateway Interface (WSGI; ウィズギー) は、
プログラミング言語Pythonにおいて、WebサーバとWebアプリケーション（もしくはWebアプリケーションフレームワーク）を接続するための、
標準化されたインタフェース定義である。また、WSGIから着想を得て、他の言語でも同様のインタフェースが作られた。

## 開発環境の構築

今回の開発環境構築は、macOS 用パッケージマネージャーの[Homebrew][brew]を利用して、作業を進めていきます。
こちら[Homebrew][brew]の環境が整っていない場合は、公式サイトを熟読の上、作業を進めてください。


### Apache2 Install
---
```bash
# apache2
brew install apache2
```

### python3 Install
---
```bash
# python3
brew install python3
python3 -m pip install mod_wsgi

cd /usr/local
find Cellar
ls -l bin
```

### WSGI Install
---
[mod_wsgi][]のインストールはまず[Source code]を入手します。
(現時点での最新は、mod_wsgi 4.5.22でした)
入手したソースコードを下記の手順で行い、[.so]ファイルを作成します。

なお、既にapacheやpythonの環境ができている場合は、
`xcode-select --install`を実行して、Xcode command line toolsが動作可能である状態にしておきましょう。

*※注意*: 下記のcommand実行は、自分の環境に合わせて、ご対応ください。
今回上記の対応で進めていた場合、環境によっては一部異なっている場合があります。

```bash:ターミナル
# configure Setting.
./configure --with-python=/usr/local/bin/python --with-apxs=/usr/local/bin/apxs

# もし上記のパスがわからない場合は、以下を試してください。

make
sudo make install
chmod 755 /usr/local/lib/httpd/modules/mod_wsgi.so
```

## Apacheの設定

httpd.confの設定

```bash:httpd.conf
# 必要最低限のみ記載あとは環境に合わせてください。
Listen 80
ServerName exmaple.com:80
Listen 127.0.0.1:80 http

# (You will also need to add "ExecCGI" to the "Options" directive.)
<Directory "/usr/local/apache2/cgi-bin">
    AllowOverride None
    Options +ExecCGI 
    Require all granted
    AddHandler cgi-script .py .cgi
</Directory>

# Virtual hosts
Include /usr/local/etc/apache/extra/httpd-vhosts.conf

```


httpd-vhosts.confの設定

```bash:httpd-vhosts.conf
LoadModule wsgi_module /usr/local/lib/httpd/modules/mod_wsgi.so

<VirtualHost *:80>
  #SSLEngine Off
  DocumentRoot /usr/local/var/www/htdocs
  ServerAdmin info@exmaple.com

  ServerName exmaple.com
  ScriptAlias /cgi-bin/ /usr/local/var/www/cgi-bin/

  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
  ErrorLog /usr/local/var/log/httpd/http-httpd-error.log
  CustomLog /usr/local/var/log/httpd/http-httpd-access.log combined

  WSGIDaemonProcess cgi-bin user=_www group=_www processes=1 threads=5 python-path=/usr/local/bin/python
  WSGIScriptAlias / /usr/local/var/www/cgi-bin/app.wsgi

  <Directory "/usr/local/var/www/cgi-bin/htdocs">
    Options Includes FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
  
  <Directory "/usr/local/var/www/cgi-bin/">
    AllowOverride None
    Options ExecCGI
    WSGIProcessGroup cgi-bin
    WSGIApplicationGroup %{GLOBAL}
    Require all granted
  </Directory>

</VirtualHost>

```

app.wsgiファイルの設定
これは、pythonファイルとしての記述と変わらず、
おまじない感覚でご利用ください。
ちなみに、wsgiをこのファイルを起点に起動確保することで、
`import`されたindexファイルが読み込まれ、動作する仕組みなっています。
cgiとなるファイルは、index.pyであり、
実際のアプリケーションファイルとなり、Python上での実行ファイルとなります。

```python3:app.wsgi
# -*- coding:utf-8 -*-
import sys, os
dirpath = os.path.dirname(os.path.abspath(__file__))
sys.path.append(dirpath)
os.chdir(dirpath)
import bottle
import index
application = bottle.default_app()
```

他のモジュールは必要に応じて、追加。
また、userとgroupは環境や権限より異なる為、
環境設定をご確認の上、変更が必要。

## まとめ
今回学んだ事は...
コレまで、開発環境をPythonだけで、本番環境とは異なった環境だったために、
いざ本番にあげたら正常に動作しないなどが多かったが、
それらを中和しつつ、「データベースとの連携、webserverとしての稼働上の問題、表示速度、外部接続時の挙動...」なども含め、
あらゆる想定もでき、本来のバックエンド側の事を意識しながら、開発できたことが一番の大きい収穫だったと思います。

また以前は、マークアップエンジニアだったので、フロントエンド側の処理経験を生かしつつ、
バックエンド側の負荷軽減なども含め、pythonだけで動くのではなく、
実際の環境でもそのまま動くモノとしてを常に意識しつつ開発ができたと思います。

今回の開発では、下記の内容が設定以外にも含まれた開発となっています。
「gzip圧縮や非同期処理でのファイルのアップロード、ログインのセッション管理、データベースの構成、システム設計、デザイン、テスト、サーバー構築、HTTPS接続、SQL、Cookieなど...」
実務を通し、実際に稼働するシステムを一人で、全て作る事でのメリットは独学の時よりも遥かに大きモノとなった思います。

以上。
最後に...
if　[環境構築などにおいて、エラーに遭遇した場合に見とくといいもの。][end]
else　学ぶ行為は、生き抜くために必要な行為だという事。

## ERRORが発生した場合
### [Erro no2][q&a]
これは、Command Line Toursの参照先、もしくは実行バージョンがOSのバージョンに合っていないために、発生するエラーである。
もしCommand Line Toursのインストール前に、古いバージョンのXcodeを先にインストールしている場合、または、複数バージョンのXcodeがインストールされている環境の場合は、これらのエラーが発生することを確認している。

対策としては、最新のXcodeインストールし直しメインにするか、常に使用しているXcode起動して、`Preferences... > Locations > Command Line Tours`の順番に進み、Command Line Toursのバージョンを最新、もしくはOSに合わせたバージョンを選択する事で、エラーが発生しなくなる。

```python:error

FileNotFoundError: [Errno 2] No such file or directory: '/Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.12.xctoolchain/usr/local/bin/apr-1-config'

```


## あとがき
一部書き方がカタコトだがこれは、海外の人がこの記事をみた時を考慮し、敢えてであり、google翻訳された時を想定し、翻訳に似せて書いてみたので、文章力は大目にみてください。

<!-- Links -->
[mod_wsgi]:https://github.com/GrahamDumpleton/mod_wsgi/releases
[wsgi]:https://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface
[q&a]:https://github.com/Homebrew/homebrew-php/issues/3283
[brew]:https://brew.sh/index_ja.html
[Bottle]:https://bottlepy.org/docs/dev/
[Django]:https://www.djangoproject.com/
[end]:#error%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88