技術と趣味となにか

ゆるくやる

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>にすればいいと分かった

参考サイト

  1. http://qiita.com/kent_ocean/items/1d8e0d6e0b853b424fcf
  2. http://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/

寝ても眠いのは違憲

※この記事はICT アドべントカレンダーの17日目の記事です.

※この記事はうちな~ICTビジネスプラン発表会の日に,

深夜2時に寝て朝の5時に起き夜の23時30分に帰ってきたのちに書かれています.

 

どうも眠そうな人(@nemu_sou )です.

昨日は強い一年生たちの強い記事でした.

potato0022.hatenablog.com

b-mk.hatenablog.com

rio-k827.hatenablog.com

 

四月に見たときはおもしろくてつよそうだなあ(小並感)などと思っていましたが、

みんな結果を残していてやはりすごかったですね。

 

とりあえず今年を振り返ってみる

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点だったこと(部分点マスターになれなかった).

感想.

会津秋葉原たのしかった.

東京の駅は人が多すぎる.

python, サーバー, ラズパイの経験値を得た.

来年はまだ時間があるからといってだらけないで開発する.

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’}]})