PythonのFlaskを初めて触ってから３０分で本番環境にデプロイ+ HTTPS通信まで完成

# はじめに

前回、Bottleで30分でデプロイ出来るところまで書き、Bottleは非常に扱いやすかったのですが、SSL通信をサポートするには `cherrypy` を使ったりと何かと面倒になってきたので、今度は Bottle と並んで軽量なPythonのWebフレームワークである Flask を使っていきます。

## 開発環境

* OS：CentOS release 6.8
* Apache：2.2.15 (Unix)
* Python 3.5.2
* mod_wsgi 4.5.6

# 環境構築からHello Flask!まで（5分）

こちらはローカル（手元のMac）で作業をしていきます。

```bash
$ pip3 install flask
```

```py:app.py
# coding: utf-8
from flask import Flask

app = Flask(__name__)

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

if __name__ == "__main__":
    app.run()
```

```bash:サーバーの起動
$ python3 app.py
```

ブラウザからローカルホストの「http://127.0.0.1:5000」にアクセスします。

<img width="125" alt="スクリーンショット 2016-11-14 1.30.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/130181/b89a7f33-0648-c6da-c55b-260a7d51ecfd.png">

Bottleと同様、超お手軽ですね。
今回は、DBの操作やテンプレートについては触れませんが、もちろんそれらも全てサポートしています。


# 本番環境でhttps通信まで

ここからはサーバー上で作業していきます。

## 環境構築（10分）

はじめに、CentOSで必要なパッケージをインストールします。

```bash
$ sudo yum groupinstall "development tools"
$ sudo yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel
$ sudo yum install  httpd-devel python-devel
```

そして、python3.5系ととパッケージ管理ツールのpipをインストールします。

```bash:python3.5とpip3.5のインストール
$ sudo su # rootで操作していきます
$ cd /usr/local/src
$ wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
$ tar zxvf Python-3.5.2.tgz
$ cd Python-3.5.2
$ ./configure --enable-shared
$ make && make altinstall
$ ln -s /usr/local/bin/python3.5 /usr/bin/python3
$ ln -s /usr/local/lib/libpython3.5m.so.1.0 /lib64/
$ python3.5 --version  # 最後にバージョンの確認ができればpythonのインストール完了
Python 3.5.2
# 同時にpip3.5もインストールされるので、シンボリックリンクを貼る
$ ln -s /usr/local/bin/pip3.5 /usr/bin/pip3.5
$ pip3.5 --version
pip 8.1.1 from /usr/local/lib/python3.5/site-packages (python 3.5)
```

本番環境にて、Apacheと連携させるために必要な mod_wsgi もインストールします。

```bash:mod_wsgiのインストール
$ cd /usr/local/src
$ wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.6.tar.gz
$ tar zxvf 4.5.6.tar.gz
$ cd mod_wsgi-4.5.6
$ ./configure --with-apxs=/usr/sbin/apxs --with-python=/usr/local/bin/python3
$ make && make install
$ chmod 755 /etc/httpd/modules/mod_wsgi.so 
```

## 組み込みサーバーでFlaskの動作確認（5分）

環境が揃ったので、まずはFlaskの組み込みサーバーで動作確認出来るところまでを解説していきます。

```bash:Flaskのインストール
$ pip3.5 install flask
```

```py:/var/www/html/app.py
# coding: utf-8
from flask import Flask

app = Flask(__name__)

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

if __name__ == "__main__":
    app.run(host="example.com", port=8000)
```

```bash:組み込みサーバーの起動
$ python3.5 app.py 
```

これで http://example.com:8000 へアクセスします。

![スクリーンショット 2016-11-14 1.39.17.png](https://qiita-image-store.s3.amazonaws.com/0/130181/13a2c102-5864-99db-f18e-cc567374943f.png)

ここまではOKです。

## Apacheとmod_wsgiで本番用サーバーを構築（10分）

Apacheの設定ファイルを編集します。

```bash:/etc/httpd/conf.d/flask.conf
# http通信はhttps通信へ強制リダイレクト
<VirtualHost *:80>
  ServerName example.com:80
  RewriteEngine on
  RewriteCond %{HTTP_HOST} ^example\.com
  RewriteRule ^/(.*)$ https://example.com/$1 [R=301,L]
</VirtualHost>
# https通信の設定はこちら
<VirtualHost *:443>
  SSLEngine on
  SSLProtocol all -SSLv2
  SSLCertificateKeyFile   /etc/httpd/conf/ssl.key/server.key
  SSLCertificateChainFile /etc/httpd/conf/ssl.crt/internal.crt
  SSLCertificateFile      /etc/httpd/conf/ssl.crt/server.crt
  DocumentRoot /var/www/html/api
  ServerName example.com:443
  CustomLog /var/www/html/access.log common
  ErrorLog  /var/www/html/error.log
  AddDefaultCharset UTF-8
  WSGIScriptAlias / /var/www/html/adapter.wsgi
  <Directory "/var/www/html/">
    options Indexes FollowSymLinks +ExecCGI
  </Directory>
</VirtualHost>
```

```bash:Apacheの再起動
$ sudo service httpd restart
```

SSL通信の鍵や設定に関して不明な点がある方は、「[さくらVPSにSSL証明書を導入しHTTPS通信の構築](http://qiita.com/carat_yoshizaki/items/e6f39a5bfb99900b44b2)」で書いていますので、こちらをご覧下さい。

wsgiファイルを編集します。

```py:/var/www/html/adapter.wsgi
# coding: utf-8
import sys
sys.path.insert(0, '/var/www/html')

from app import app as application
```

つぎに、さきほどの `app.py` も本番環境に合わせて多少変更します。

```py:/var/www/html/app.py
# coding: utf-8
from flask import Flask

app = Flask(__name__)

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

if __name__ == "__main__":
    app.run()
```

変更点は以上になります。
これで、https://example.com にアクセスしてみましょう。

![スクリーンショット 2016-11-14 2.13.32.png](https://qiita-image-store.s3.amazonaws.com/0/130181/8aacf60f-1283-419d-d2e8-95c99c1fd604.png)

見た目は同じですが、https://... で動作しているはずです。

# まとめ
FlaskはBottle同様に軽量でありながら、SSL通信まで非常に簡単に実装することができました。
また、Bottleと比較すると、解説記事の数が雲泥の差というほど多いです。


# おまけ

フォローお待ちしています！

* Qiita: [Carat 吉崎](http://qiita.com/carat_yoshizaki)
* twitter：[@carat_yoshizaki](https://twitter.com/carat_yoshizaki)
* はてなブログ：[Carat COOのブログ](http://carat-tech.hatenablog.com/)
* ホームページ：[Carat](http://caratinc.jp)

サービス紹介
「数学→プログラミング→Webアプリケーション」まで一気に学べる機械学習のマンツーマン家庭教師サービス「[キカガク](https://kikagaku.net)」に興味のある方はお気軽にご連絡ください。