クッキーもぐもぐ

PC関係とか映画とかゲームとかの

GCE: Flask + uWSGI + nginx でhello world表示

前置き

先日作ったGoogle Cloud Engine(GCE)にFlaskを使って"Hello world"を表示させた

その手順、メモ、学んだことをここに書く

独学なので結構間違えてることも、あるかも・・・?

環境

参考

以下のサイトを主として参考にさせて頂いた

Flask + uWSGI + Nginx でハローワールドするまで @ さくらのVPS (CentOS 6.6)

【Pythonで多分人気2位のWebアプリケーションフレームワーク】Flaskの基本をわかりやすくまとめる

Ubuntu 16.04 で Flask アプリケーションを動かすまでにやることまとめ

大まかな手順

  • 各機能の役割についてメモ
  • flaskのインストール、疎通確認
  • nginxのインストール 、疎通確認
  • uWSGIのインストール
  • 各種設定、疎通確認

各機能の役割について

サーバーは、OSという脳みそとフレームワークという雑務処理みたいなのがいれば、最低限機能する

イメージ

Framework <-> Client(ユーザ)

ユーザからhttp(https)で、リクエスト(これくれ~)がきたとき、応じて適切なものを上げる。
ユーザはそれを受け取ってブラウザで表示する。
だけどFramework(とくにFlaskのような小規模むけのもの)だけだと同時多数のアクセスには対応できない。
一度に大量の受付を処理できずパンクしちゃう。

f:id:christmas-cookies:20180813190821p:plain

そこでユーザとフレームワークの間に入って受付担当してくれる仲介人を入れておけば、同時アクセスにも対応できるようになる。
それがwebサーバー。nginxやapacheとか。
フレームワークとwebサーバーもいろいろ種類があるので、その相性をよくするため、さらに間に入って仲介してくれるものをいる。
それがWSGI(uWSGIとの違いがよくわからなかった・・・すいません)
これで大量の同時アクセスにも対応できるようになる。

f:id:christmas-cookies:20180813190901p:plain

Framework <-> uWSGI <-> Web Server <-> Client(ユーザ)

nginx, uwsgiについての参考サイト

【Django入門】Nginxを使ってWebサーバーを動かそう | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト

WSGI(Web Server Gateway Interface)の役割

なので始めはフレームワークをインストール+表示(疎通)確認。

次にnginxをインストール+疎通確認

uwsgiをインストール

最後に各設定ファイルを作成し、flask<->uwsgi<->nginxで疎通確認を行う。

ちなみにGCEの場合、VMインスタンスで「ブラウザウィンドを開く」を選択し、そこにコマンドを打っていけばOK。

f:id:christmas-cookies:20180813191345p:plain

flaskのインストール、表示テスト

OSにFlaskを入れる。
Flaskは言語がpythonなので、まずpython,pipを入れる。

ubuntuではインストールにaptコマンドを使う。
aptとはubuntuのパッケージ管理。

[Ubuntu] apt-get まとめ

まずは既に入っているパッケージのアプデと内容確認

apt update #パッケージリストの更新
apt upgrade #インストールされてるパッケージの更新
dpkg -l #インストールされてるパッケージの一覧

確認したあと、pythonとpipを入れる。
pythonはver3。
pipとは、pythonのパッケージの管理システム。
なのでubuntu全体に関するものはaptで、python関係はpipでインストールしていく。

ちなみにGCEでubuntuだとpythonははじめから入っている。
入っていなければ以下で入れる。

apt install python3 #python3のインストール
apt install python3-pip #pipのインストール
pip3 install flask #flaskのインストール

これでフレームワークのインストールは終わり。
とてもシンプル。

試しに簡単な表示を行う。

今回はhomeフォルダの下にgacha_yosoというフォルダを作成し、その下にapp.pyを作った。 (プロジェクトフォルダの場所、名前、app.pyの名前は自由)。

cd /home #ホームへ移動
sudo mkdir gacha_yoso #フォルダ作成
cd gacha_yoso #フォルダ移動
sudo touch app.py #ファイル作成
sudo vi app.py #vimでファイル編集

app.pyには以下の内容を入れる。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "hello world"

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=80)

ここでちょっとvim関係のメモ

iでインサートモード
vimでペーストする場合、windowsからだとshift+insertでペーストできる
:wq で保存、終了

sudo vi でvimにしておかないと権限でうまくいかない
単純なvi でやった場合、:w,:qに以下を追加することで強制的に書き込みできる
:w !sudo tee % :q!

viコマンド基本

【touch】Linuxで新規ファイル作成をするコマンド | UX MILK

クリップボードを経由する貼り付け方法 < 全般 < 初級編 | viエディタ入門

権限

書き込み権限のないユーザでファイルを編集してしまったとき Can't open file for writing - MEMOcho-

ポイントなのが

 app.run(host="0.0.0.0",port=80)

のところ。
ローカルで確認ならば、app.run()でOKなのだがflaskはデフォルトで外部サイトに公開していない設定+portが5000なので
host="0.0.0.0"で外部にも公開ですよ~
port=80でポート80で公開ですよ~ 
と指定しやる(GCEはpoort80が開放されている

この設定により、flaskだけで簡易的なサーバーが完了する

ちゃんと設定がうまくいているか確認する

sudo python3 app.py

これで起動
この状態で

http://xxxxx:80 (xxxはGCEで設定したIPアドレス

にアクセスし、

hello world

と表示されればOK。(スマホからも表示されるのはちょっと感動^^

終了に関するメモ
ちなみにctrl+cでpythonを終了できるが、うまく終了できない場合があった。
そういうときは

ps -fA | grep python

でむだなpythonプロセスが動いてないか確認。

app.py~ のように表示されてて、まだ動いているようであれば、プロセスIDを控え
sudo kill -9 プロセスID

で強制的に終了させられる

Nginxインストール

apt install nginx

これだけ

試しに
http://xxxxx(xxxはGCEで設定したIPアドレス にアクセスし、welcome to nginx 的な表示がされればちゃんとwebサーバーが入っているはず。

uWSGIインストール

uWSGIをインストールする。
参考にしたサイトではaptではなくpip経由が多かった。

pip3 install uwsgi

これでOK

各疎通テスト

flaskでの疎通確認をした
nginxでの疎通確認もした

つまり

flask<->cliant
nginx<->cliant

がOK

ここでnginx、uwsgiの設定ファイルを作成することで
flask<->uwsgi<->nginx<->cliantを実現させる

まずnginxの設定
簡単にいうと/etc/nginx/下に設定を作成する
実は設定ファイルを置く場所が複数あってややこしい(別記事で詳しく書く予定)
centosだとconf.d下に設定ファイルを置く
ubuntuだとsites-available下にファイルをおき、sites-enabledにそのショートカットを作っておく

参考 nginxでsites-availableとsites-enabledを用いたバーチャルホストの設定 - YoshinoriN's Memento

├── conf.d
│   └── default.conf←centosはここに設定ファイル
├── nginx.conf
├── sites-available←ubuntuはここに設定ファイル*
│   └── default
└── sites-enablede←*ここにそのショートカット
    └── default
cd /etc/nginx/sites-available #移動
sudo touch uwsgi #名前はなんでもよい
sudo vi usgi

ファイルの中身は以下のようにすればOK

server {
    listen       80;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
}

簡単に説明すると、nginxにきたアクセスはuwsgiに任せるで~という指示が書いてある
(つまり、nginxに情報がきたら(httpによるアクセス)、uwsgiに担当させるで~

sites-enabledeフォルダに今作ったファイルのショートカット(正確にはシンボリックリンク)を作る

ls -s リンク元ファイル ショートカット先

今回だと

ls -s /etc/nginx/sites-available/uwsgi /etc/nginx/sites-enablede/uwsgi 

sites-enabledeのdefaultは削除しておく

cd  /etc/nginx/sites-enablede
rm default

これにより、元はsites-enabledeのdefaultショートカット=sites-availableのdefaultを参照だったのが、
sites-enabledeのuwsgiショートカット=sites-availableのuwsgiを参照するようになった

ちなみに、そのファイガシンボリックリンクかどうかは

ls -l

で確認できる

あとはnginxを再起動して設定ファイル

systemctl restart nginx.service #nginx再起動
sudo nginx -t #nginx自体に問題ないか確認

これでsuccessfulみたいな言葉がでればOK

ちなみに

systemctl enable nginx #自動的に起動
sudo service nginx stop #停止

次にuwsgiの設定 uwsgi自体は

uwsgi  (いろんなパラメータ設定の引数)

で起動できる。
けど毎回、パラメータを書いて起動するのはめんどくさい。
そこでパラメータをまとめてかいた設定ファイルをしておき、

uwsgi (設定ファイル読み込み)

として起動させるようにする。
設定ファイルはflaskのプロジェクトフォルダに作る

cd home/gacha_yoso #移動
sudo touch myapp.ini #ファイルの名前はなんでもよい
sudo vi myapp.ini

ファイルの内容

[uwsgi]
module = app
callable = app
master = true
processes = 1
socket = /tmp/uwsgi.sock
chmod-socket = 666
vacuum = true
die-on-term = true

moduleはモジュール、つまりflaskで作ったapp.pyのファイル名
socket はnginxで書いたソケット
これでuwsgi<->nginxがつながる

これで

uwsgi --ini myapp.ini

によって、uwsgiを起動(+設定ファイル読み込み)できる

この状態で http://xxxxx にアクセスすると、python3 app.pyと指定なくてもhello worldと表示されるはず。

ここでwelcom to nginxと表示された場合
nginx<->uwsgi間の設定がうまくいっていない可能性がる。

ちなみに、これでうまく言っている場合、app.pyの app.run(host="0.0.0.0",port=80)はrun()にしてOK。

まとめ

ubuntu+flask+uwsgi+nginxの環境構築を行い、hello worldを表示させた

やったこと自体はfalsk,uwsgi,nginxの各インストール、設定ファイルの作成

インストールはどれも1行で終わる

設定ファイルはnginxだけ気をつける(OSによって変わる)

実行内容じたいはとてもシンプルだが、結構ハマりやすい要素が多く、各項目において確認する作業が大事だと痛感

今後

sshの設定とかgit cloneでファイルをごそっと持ってきたりしたい