Bottle + uWSGI+ Nginx Quick Tutorial

Bottle簡単でいいんだけど、いざ自前のサーバーにデプロイするとなると案外知らないことが多くて結構調べたので、まとめ。

# Bottleってなに？？
[公式サイト](http://bottle.readthedocs.io/en/latest/)によれば

*Bottle is a fast, simple and lightweight WSGI micro web-framework for Python.*

__Pythonで簡単にWebページが作れるツールだよ！__
ってことです。

ちなみになんと本体はたったの1ファイル。これをほかのPythonモジュールと同じようにimportしてあげればすぐ使えて、そのまま実行すればWebページが立ち上がる。スゴイ。

# やること
1. Bottle で簡単なWebページを立ち上げる@ local
2. 外部公開へ向けて
2. uWSGIとNginxのセットアップ

# 準備
サーバーにPython2系が入ってる前提。以下OSはUbuntu 14.04LTS。

まず、必要なものを整える。

```shell-session
$ sudo apt-get install -y uwsgi uwsgi-plugin-python python-bottle nginx
```

一瞬である。

# Bottle　はろーわーるど

[公式サイト](http://bottle.readthedocs.io/en/latest/)からコピペしてきたぞ！

```py:app.py
from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

run(host='localhost', port=8080)
```

これを`~/www/bottle_hello/`に配置した。
早速確かめてみよう。

```shell-session
$ python app.py
Bottle v0.12.0 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
```

```shell-session
$ wget http://localhost:8080/hello/kabocha
--2016-12-02 22:42:10--  http://localhost:8080/hello/kabocha
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... failed: Connection refused.
Connecting to localhost (localhost)|127.0.0.1|:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 21 [text/html]
Saving to: ‘kabocha’

100%[============================================================================>] 21          --.-K/s   in 0s

2016-12-02 22:42:10 (727 KB/s) - ‘kabocha’ saved [21/21]

$ cat kabocha
<b>Hello kabocha</b>!
```

おぉ。

# デプロイへ
先ほどはBottleが持ってるビルトインサーバーが立ち上がっていた。
ただ貧弱なので、デプロイするにあたり別のWebサーバーを導入する。
[WSGI]()準拠であればなんでもよいが、今回はuWSGIを使う。


構成としては、

`web -> Nginx -> uWSGI + Bottle`

といった形。Nginxが外からデータを受け取り、uWSGI上で動くBottleへとつないでいます。

まずWebサーバーと連携するために、先ほどの`app.py`を

```py:app.py
from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

if __name__ == '__main__':
    run(host='localhost', port=8080)
else:
    application = default_app()
```

こうしておく。

# uWSGIの設定

uWSGIはデフォルトで起動するとrootユーザーで起動するので、`uid`　`gid`オプションでユーザーを変える。
それに合わせて、予め権限変更をしておく。

```shell-session
$ sudo mkdir /var/run/uwsgi/
$ sudo chown www-data:www-data /var/run/uwsgi/
$ sudo mkdir /var/log/uwsgi
$ sudo chown www-data:www-data /var/log/uwsgi
```

次いで、設定ファイルの用意。まず以下のini file を用意する。
ディレクトリの場所、Nginxとのやり取り方法(socket)を記す。

```ini:/etc/uwsgi/apps-available/bottle_hello.ini
[uwsgi]
master = true
plugins = python
chdir = /var/www/bottle_hello/
file = app.py
socket = /run/uwsgi/app/bottle_hello/socket
chmod-socket = 666
uid = www-data
gid = www-data
```

シンボリックリンクを張って、再起動。

```shell-session
$ sudo ln -s /etc/uwsgi/apps-available/bottle.ini /etc/uwsgi/apps-enabled/bottle.ini
$ sudo service uwsgi restart
```

これでuwsgiはおｋ。



# Nginxの設定

confを用意する。
先ほど指定したsocketで通信する。

```nginx:/etc/nginx/conf.d/bottle_hello.conf
upstream _bottle {
    server unix:/run/uwsgi/app/bottle_hello/socket;
}

server {
    listen 80;
    access_log  /var/log/nginx/bottle_hello.log;
    location / {
        include uwsgi_params;
        uwsgi_pass _bottle;
    }
}
```
そしてリスタート

```shell-session
$ sudo service nginx restart
```


今回、ipアドレス直打ちでアクセスするので、server_nameとかは設定しない。なおこの場合、`/etc/nginx/sites-available/default` `/etc/nginx/sites-enabled/default`に記載されてるデフォルト設定が優先されるので、これらのファイルは別フォルダに退避した。

あんまりよくないので、実運用ではlocationを工夫したり、ちゃんとドメインを設定して対処すべきだと思う。


# 以上！
以上！Bottleはほんとお手軽だなぁ。
実は最後のデフォルト設定が優先されるところで２、3時間つまっていたのは内緒。