やりたかったこと(できたこと)
- flaskアプリケーションをwebサーバーで公開したい
- ローカルのmacで動作確認して、awsのec2(ubuntu)で公開
環境
- mac
- OS High Sierra 10.13.1
- Python 3.6.1
- Apache 2.4.41
- aws ec2 t2.micro
- Ubuntu 16.04.3 LTS
- Python 3.5.2
- Apache 2.4.18
事前知識
- Pythonは慣れてたけど、flaskは初めて
- バックエンドはほとんど知らない
- webサーバーとパソコンって何が違うんだっけ?レベル
- ローカルホスト、グローバルIP、プライベートIPとか良く分かんない
理解したこと(雰囲気)
※厳密ではないです
-
Webサーバーって何ぞや?
- ブラウザのアドレスバーに自分のIPアドレスが打ち込まれたときに、Webページを返すやつ
- 他者からはグローバルIPで接続(LAN内ならプライベートIPで可)。自分はlocalhostでも可
- パソコンにwebサーバーソフト(Apacheとか)入れて起動させれば、ほぼWebサーバー
-
flaskだけではだめなのか?
- 実はflaskだけでも公開は可能(flaskだけでHelloWorld表示できるのは、flaskがwebサーバー機能を持っているから)
- あくまで確認用の最低限の機能であって、セキュリティーとか処理速度とかがダメなので非推奨らしい
-
flask、Apache、wsgiの関係
- Apacheはwebサーバーとして優秀。基本的なところはApacheにやらせたい
- flaskにしかできないとこだけflaskにやらせたい
- webサーバーとflaskとを上手く繋げて動作させるために、wsgiが必要。wsgiはミドルウェアとも考えられる
- Apache用のwsgiは、mod-wsgiというモジュール名
手順概略
ハマって色々やりましたが、基本的な手順は下記(だったと思います)です
(途中で「gccが入ってないからインストールしろ」とか言われることはありえます)
-
セットアップ
- apache2、apache2-devのインストール
- mod-wsgiのインストール(pip)
- ec2ではpython3-devもインストールした
-
実行、動作確認
- コマンドを打つ:mod_wsgi-express start-server
- ブラウザで確認: http://localhost:8000
- ec2の場合は、macのブラウザなどから http://【グローバルIP】:8000
ec2の場合はec2のサービスページにて下記作業が必要です
・セキュリティーグループでカスタムTCPでポート8000を設定
・グローバルIPを確認
各項目の詳細は下部にて。
apache2、apache2-devのインストール
すでに入れてらっしゃる方も多いと思いますが、なければ入れましょう。
システムによって名前はちょっと違います。詳細はpypiのmod-wsgiページの「System Requirements」参照
mod-wsgiのインストール(pip)
概略:GitHubのリポジトリをクローンし、setup.pyを使ってインストールします
GitHubのリポジトリ
https://github.com/GrahamDumpleton/mod_wsgi
をクローンして、そのディレクトリに移動し、下記実行します
python3 setup.py install
これでpip install mod-wsgiが出来る状態になります。なのでやりましょう
pip install mod-wsgi
注意点
- python2ではなく3が動くように注意しましょう
- python --versionなどでpython3が動いているか確認
- 自分のec2の場合は、mod-wsgiのインストールの際にpython3-devを入れないとダメでした
- 他の方法でインストールしたmod-wsgiは邪魔なのでアンイントールしましょう
- 「apt-get install libapache2-mod-wsgi」などでインストールしたものなど
- apacheのコンフィグファイルを書き換えていたら元に戻しましょう。実行時にエラーになることがあります
- エラーが出たら、読めるところは頑張って読みましょう
- configファイルに余計な記述があるとか、モジュールが足りないとかは読めると思います
実行、動作確認
下記コマンド実行
mod_wsgi-express start-server
macのブラウザで「localhost:8000」にアクセス
エラーなくヘビのウィスキー漬けみたいなのが表示されればOKです
ただし、これはまだflask使ってないです
(「apachectl start」ではポート80なので、こちらは完全に別で動いているみたいですね)
##自分で作ったページを表示(flaskなし)
カレントディレクトリに下記ファイルを作ります
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
そして
mod_wsgi-express start-server test_1.py
を実行して、localhost:8000を確認しましょう。Hello Worldが表示されていればokです
flaskとの連携
最後に、flaskとの連携です。最小限の構成とします。
下記2ファイルをカレントディレクトリに作成します
import sys
import os
sys.path.insert(0, os.getcwd())
from test_flask import app as application
from flask import Flask
app = Flask('any name')
@app.route("/")
def hello():
return "Good Morning, flask"
そして
mod_wsgi-express start-server test_2.py
を実行し、localhost:8000にアクセスします。「Good Morning, flask」が表示されればOKです
ec2でも同じように動き、LAN外のスマホから 【グローバルIP】:8000 にアクセスして表示されることを確認できました
(ec2はセキュリティグループでポート設定するのを忘れていて手こずりましたが)
終わりに
以上でヤマは越えたと思います。
flaskとwebサーバーとの連携が想像以上に大変でしたが、これで今度こそ、flaskアプリをすぐに公開できる状態になったはず...!
参考
https://pypi.org/project/mod-wsgi/
https://modwsgi.readthedocs.io/en/develop/index.html