ユーザーディレクトリ上のFlaskアプリをApacheで公開する

# 概要
User directoryにあるFlask (Python)で作られたWebアプリをApacheで公開する方法

# 免責事項

- ここに記載されている方法は、私がApacheの仕組みを完全に理解して作成したものではありません。
- ここに記載されている方法を利用される際は、自己責任にて実行してください。

（改善すべき点がありましたら、コメントをお願いいたします。）


# 環境
- RaspbianとDebian9.4にて動作を確認した
- 今回の動作例は以下の環境で行われている

```shell-session:動作例の環境
pi@raspberrypi:~ $ cat /etc/issue
Raspbian GNU/Linux 9 \n \l
pi@raspberrypi:~ $ python3 --version
Python 3.5.3
```

# ソフトのダウンロード

## apt
```shell-session:apt
$ sudo apt install python3-dev python3-pip  # python3 関連
$ sudo apt install apache2 libapache2-mod-wsgi-py3  # apache 関連
```

もちろん、下記のように一緒にインストールしても良い

```shell-session:全部まとめて
$ sudo apt install python3-dev python3-pip apache2 libapache2-mod-wsgi-py3
```

## pip3
```shell-session:pip3
$ sudo pip3 install flask
```

# 動作例
PUBLIC_FLASK、flask_appは任意

## ファイル構成
```shell-session
pi@raspberrypi:~/PUBLIC_FLASK $ tree -l
.
├── flask_app.py
├── flask_app.wsgi
└── templates
    └── hello.html

1 directory, 3 files
```
- staticディレクトリを作成する際は```~/PUBLIC_FLASK/static```というふうに置けばよい

## flask_app.py
- デバッグのために、app.runに引数を書くことは構わないが、必ず```if __name__ == "__main__":```の下に書くこと

```python:flask_app.py
# -*- coding: utf-8 -*-

from flask import Flask, render_template
app = Flask(__name__)


@app.route("/")
def hello():
    return "Hello World!"


@app.route('/<name>')
def hello_name(name=None):
    return render_template('hello.html', name=name)


if __name__ == "__main__":
    app.run()
```
## flask_app.wsgi
- Apacheにpythonのファイルを読み込ませるため（たぶん）に、wsgiファイルを作成する
- 動作例では、wsgiのファイル名がpythonのファイル名と同じになっているが、同じでなくても構わない（はず）

```python:flask_app.wsgi
import os,sys

sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))

from flask_app import app as application
```
## templates/hello.html

```html:templates/hello.html
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}
```


                         



# Apacheの設定

- userdir.confを編集する 
- ユーザー名やパス（4箇所）の変更のし忘れに注意！
- この例では、ユーザー名はpiとなっている

```shell-session:/etc/apache2/mods-available/userdir.conf
<IfModule mod_userdir.c>
    UserDir PUBLIC_FLASK
    UserDir disabled root

    WSGIDaemonProcess flask_app user=pi group=pi threads=5
    WSGIScriptAlias / /home/pi/PUBLIC_FLASK/flask_app.wsgi

    <Directory /home/pi/PUBLIC_FLASK>
        AllowOverride FileInfo AuthConfig Limit Indexes
        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        Require method GET POST OPTIONS

        WSGIProcessGroup flask_app
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```
- userdir.conf を有効にする

```shell-session
$ sudo a2enmod userdir
```

- Apacheを再起動

```shell-session
$ sudo systemctl restart apache2
```
## 再起動時にエラーが発生した場合

### AH00558
以下のコマンドを実行 && Apacheの再起動

```shell-session
$ sudo echo ServerName $HOSTNAME > /etc/apache2/conf-available/fqdn.conf
$ sudo a2enconf fqdn
```
### その他のエラーで考えられる要因
- /etc/apache2/mods-available/userdir.confにてユーザー名などの書き換え忘れ

（設定を変更したら、Apacheの再起動を行うこと）

# 表示例

![HelloPython.png](https://qiita-image-store.s3.amazonaws.com/0/232491/4dcf340c-9cd3-aed5-7665-96e29ab11e3a.png)



# 参考文献
[UbuntuのApacheでFlaskを用いてPython3でWebアプリケーションを作る](http://blog.akashisn.info/entry/%3Fp%3D258)
[ApacheでUserdirを使用できるようにする。](http://d.hatena.ne.jp/Fiore/20080310/1205127955)