Flaskアプリケーションをuwsgi + nginxで動かしてみた
やってみる理由
去年のPCK(パソコン甲子園)で作ったアプリ「ふぁみここ」でサーバー側としてFlaskアプリケーションを実装しました.
その時は, uWSGIやnginxは名前だけ知っている状態でPCK本番もFlaskのrunメソッドで動かしていました.
※Flaskのrunメソッドは開発で使うもので, 実際にサービスを提供するためのものではないそうです.
前日夜と本番中, サーバーのメモリ使用率が爆発して数十分間サーバーにアクセスできない事態が起き, 今後それを回避するため uwsgi + nginx での動かし方に挑戦してみました.
環境構築
基本環境 : VMware, Ubuntu 16.04
インストールするもの
sudo pip3 install flask uwsgi sudo apt-get install nginx
ディレクトリの作成
mkdir ~/python/flask/1/
個人的にできるだけ/ディレクトリ以下をごちゃごちゃさせたくなかったので
基本的にhomeディレクトリのしたで作業しました.
flaskアプリの作成
cd ~/python/flask/1/ vim app.py
Flaskの公式ドキュメントのものを使います.
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, World!' if __name__ == '__main__': app.run()
uwsgi設定ファイルの作成
flaskアプリと同じディレクトリで作業します.
vim uwsgi.ini
ここで'~‘を使って指定するとNo such file of directoryと怒られるので注意しましょう.
[uwsgi] #application's base folder base = /home/nemu/python/flask/1/ # /home/user_name/python/flask/1/ #python module to import app = app # app = app_nameを入れる module = %(app) #socket file's location socket = %(base)/uwsgi.sock #socket = /var/www/flask/tmp/uwsgi.sock #socket = /tmp/uwsgi.sock #permissions for the socket file chmod-socket = 666 #the variable that holds a flask application inside the module imported at line #6 callable = app #location of log files logto = %(base)/log.txt #logto = /var/log/uwsgi/%n.log master = true processes = 1 vacuum = true die-on-term = true
nginx設定ファイルの作成
sudo vim /etc/nginx/sites-enable/uwsgi.conf
server { listen 8080; error_log /home/nemu/python/flask/1/error.txt warn; location / { include uwsgi_params; #uwsgi_pass unix:///tmp/uwsgi.sock; #uwsgi_pass unix:///var/www/flask/tmp/uwsgi.sock; uwsgi_pass unix:///home/nemu/python/flask/1/uwsgi.sock; } }
設定の確認
sudo service nginx testconfig
[fail]とでたら間違っている場所を探しましょう.
[OK]とでたら設定を読み込ませます.
sudo service nginx reload
uwsgiを動かす
flaskアプリがある場所で作業します.
uwsgi --ini uwsgi.ini
ブラウザから127.0.0.1:8080
にアクセスしてHello, World!が表示されると成功です.
やってて困ったこと
- ‘~'を使ったディレクトリ指定で怒られた
- /home/<user_name>/ で指定した
- .confファイルでセミコロンをつけ忘れた
- /var/log/nginx/にerror.logというファイルがありそれを見て分かった
- この記事ではやってないが, 参考サイト1でnginxに権限を与えているところでユーザー指定が不正と言われた
- 参考サイト2で
nginx:nginx
の場所を<user_name>:<user_name>
にすればいいと分かった
- 参考サイト2で
参考サイト
寝ても眠いのは違憲
※この記事はICT アドべントカレンダーの17日目の記事です.
※この記事はうちな~ICTビジネスプラン発表会の日に,
深夜2時に寝て朝の5時に起き夜の23時30分に帰ってきたのちに書かれています.
どうも眠そうな人(@nemu_sou )です.
昨日は強い一年生たちの強い記事でした.
四月に見たときはおもしろくてつよそうだなあ(小並感)などと思っていましたが、
みんな結果を残していてやはりすごかったですね。
とりあえず今年を振り返ってみる
1月 : たぶんだらだら競プロしてた.
2月 : 同上
3月 : 競プロをやるならとりあえずAOJ100問解けと教授に言われて100問解いた.
結果的には開発組としてPCKモバイル部門のメンバーになった. (ここからPCKが終わるまで競プロはほぼAtCoderしかしなかった.)
4月 : アイディア出しに苦しむ.
5月 : 同上
6月 : アイディア出しと企画書に苦しむ.
7月 : 企画書提出二週間後に結果発表、予選通過.
8月 : 頭のなさ+テストの合間ということで数学甲子園が爆発した. 夏休み突入.
9月 : (pythonわからず && サーバーわからず && ラズパイわからず)でめっちゃぐぐってたくさんコードを書いて消した.
10月 : すこしずつわかってきたものの頭のないコードをはやしまくった.
11月 : パソコン甲子園. ベストデザイン賞をとった. latteぷろとwingぷろに出会う.
12月 : JOI予選, 20点足りずBランク. mitoの頑張りによりうちな~ICTビジネスプラン発表会で受賞.
おもしろかったこと.
PCK競技予選に相方(@RINPANMAN0606 )が一時間半遅刻してきた.
PCKで送る郵便物の紙を無限に書き間違えた.
PCKのハイライトがしゅりで埋まった.
PCK会場ですぐ近くに日本有数の進学校の人々がいた.
latteぷろがイケメンだった.
温泉さいこう.
くやしかったこと.
ベストデザイン賞でチーム名を呼ばれた時, 受賞した嬉しさよりもグランプリを取れなかった悔しさのほうが先に来た.
JOI予選通過まであと20点だったこと(部分点マスターになれなかった).
感想.
東京の駅は人が多すぎる.
来年はまだ時間があるからといってだらけないで開発する.
JOIに落ちたけど逆に競プロモチベが今まで通りある. これは競技の強い人たちにいつか会いたくなったため.
年度末の学校の表彰でICT委員会の人々が無限に呼ばれるのが楽しみ.
来年やりたいこと(目標)
競プロ(PCKがんばる, 実装力, 考察力をみにつける<-これは開発にもつながる).
pythonを軸にいろんな知見を得る(小さなツールとかたくさん作ってみたい).
数学と仲良くなる.
まとめ
来年も, この不思議でおもしろくてつよい人たちが集まるICT委員会でたくさんおもしろいことができるようにがんばりましょう.
疲れた深夜のテンションで書いたのでとても雑な文章ですが, ここまで読んでくれてありがとうございました.
今日は僕以外にも一年生が二人記事を書いてくれています. ぜひ読みましょう.
//roy-lの記事
//Shoの記事
明日は禁止された宗教における神の一人であるところのmitoくんです.
//mitoの記事
楽しみで夜も眠れませんね.
そりでは, ぽやしみ~.
MongoDB 操作入門
mongoDB 起動/再起動/停止
$ sudo service mongod start $ sudo service mongod restart $ sudo service mongod stop
mongo shellの起動
$ mongo
DBの作成・選択/選択しているDBの詳細/削除/表示
> use データベース名 > db.stats() > db.dropDatabase() > show dbs
collectionの作成/詳細/削除
> db.createCollection('collection名'); > db.collection名.stats() > db.collection名.drop()
document操作
データ挿入
> db.collection名.insert({"name":"nemu_sou"})
複数データ挿入
> db.collection名.insert({name:"nemu_sou", hoby:"programming"}) > db.collection名.insert({name:"nemu_sou", hoby:"programming", age:16}) > db.collection名.insert({name:"nemu_sou", hoby:["programming", "sleep", age:16})
document表示
> db.collection名.find()
document検索の条件指定
> db.collection名.find(条件) > db.collection名.find({name:"nemu_sou"}) > db.collection名.find({name:"nemu_sou", hoby:"programming"}) > db.collection名.find({member:["nemu_sou", "kurokoji", "mito", "luz"]}) > db.collection名.find({member:{ $in:["nemu", "mito"]}})
条件の例
演算子 | MongoDB | 意味 | sample |
---|---|---|---|
< | $lt | 右辺より小さい | {age:{$lt:100}} |
<= | $lte | 右辺以下 | {age:{$lte:100}} |
> | $gt | 右辺より大きい | {{age:{$gt:100}} |
>= | $gte | 右辺以上 | {age:{$gte:100}} |
!= | $ne | 等しくない | {name:{$ne:‘mr.a’}} |
該当なし | $in | 要素が含まれているか | ({member:{ $in :[“nemu”, “mito”]}}) |
該当なし | $exists | フィールド(列)自体の存在チェック | ({name:{$exists:false}}) |
OR | $or | $orで指定する条件のいずれかを満たすものを抽出 | ({$or:[{name:“nemu_sou”}, {hoby:‘sleep’}]}) |