arrange uwsgi with bottle in ubuntu

Nginx 快速部署Bottle+Uwsgi

1. 安装

安装 uwsgi 和 Bottle 框架

sudo apt-get install uwsgi uwsgi-plugin-python python-bottle nginx

2. Bottle程序结构

/var/www/webapp/
    plugins/
        __init__.py
    static/
        css/
        files/
        images/
        js/
    views/
        base.tpl
        page.tpl
    app.py

app.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import bottle
app = application = bottle.Bottle()

@app.route('/')
def show_index():
    '''
    The front "index" page
    '''
    return 'Hello world!'

class StripPathMiddleware(object):
    '''
    Get that slash out of the request
    '''
    def __init__(self, a):
        self.a = a
    def __call__(self, e, h):
        e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')
        return self.a(e, h)

if __name__ == '__main__':
bottle.run(
app=StripPathMiddleware(app),
    reloader=True,
    host='0.0.0.0',
    port=10059)

reloader=True 有代码变化的时候,自动加载。

3. 启动服务

python app.py

在浏览器里访问http://127.0.0.1:10059就能看到返回

4. 配置uwsgi

编辑uwsgi配置文件, sudo vim /etc/uwsgi/apps-available/bottle.ini

[uwsgi]
socket = /run/uwsgi/app/bottle/socket
chdir = /var/www/bottle
master = true
plugins = python
file = app.py
uid = www-data
gid = www-data

同nginx一样的操作,做一个软连接 ln -s /etc/uwsgi/apps-available/bottle.ini /etc/uwsgi/apps-enabled/bottle.ini

启动uwsgi,sudo service uwsgi restart

由于使用的是socket的方式,不能通过浏览器来访问,所以需要nginx来代理一下。

5. 配置nginx

编辑配置文件,sudo vim /etc/nginx/sites-available/bottle.conf

upstream _bottle {
    server unix:/run/uwsgi/app/bottle/socket;
}

server {
    listen [::]:80;
    listen 80;
    server_name app.test.com;
    root /var/www/bottle;

    location / {
        try_files $uri @uwsgi;
    }

    location @uwsgi {
        include uwsgi_params;
        uwsgi_pass _bottle;
    }
}

同样做一个软连接到sites-enabled目录下, sudo ln -s /etc/nginx/sites-available/bottle.conf /etc/nginx/sites-enabled/bottle.conf

测试并生效配置文件,sudo nginx -t & sudo service nginx reload

现在就可以在浏览器里来直接访问了http://127.0.0.1

6.配置git hooks

这样服务就可以跑起来了,然后在配置git,来随时可以提交代码更新。

在本地文件夹生成仓库git init

添加远程仓库git remote add origin http://xx.xx.xx/bottle.git

添加文件到仓库 git add .

提交到仓库git push origin master

配置一个git 的 hooks来在提交到仓库的时候,自动去拉取新的代码。

找了一下,需要配置post-receive这个hooks,在提交完成后会自动调用。

1
2
3
4
5
#!/bin/sh
unset $(git rev-parse --local-env-vars)

cd /xxx/bottle
/usr/bin/git pull

都配置好了,随便修改一点试试,然后提交,结果,并页面并没有刷新,登上服务器看一下,代码是有更新,重启一下uwsgi,结果就出来了,看来是uwsgi没有自动更新,继续找。

7.uwsgi自动加载

使用uwsgi和nginx做服务器和django框架,为什么每次修改代码都需要重启uwsgi呢?

遇到一个一样的问题

还有一种方法配置“py-autoreload = 1”,每次修改代码会自动reload,不再需要手动重启。

修改一下uwsgi的配置

[uwsgi]
socket = /run/uwsgi/app/bottle/socket
chdir = /home/yangch/www/bottle
master = true
py-autoreload = 1
plugins = python
file = app.py
uid = www-data
gid = www-data

然后重启一下uwsgi,sudo service uwsgi restart

再次提交代码,就可以看到更新了

遇到的问题

hook的问题

git 系统中 post-receive 钩子不能正常执行 git pull 解决方法

有一个需求是本地git在push到远程 git repo 之后,在远程服务器上自动在/dir/foo下执行 git pull 的操作。想来是一个很简单的需求,不就是在远程的 foo.git 仓库中的 hook 里加一个 post-receive 的钩子,然后在钩子里加入一个 git pull 的操作。但是实际操作的时候发现有问题的,因为这样忽略了一个小细节的问题。

操作之前,头脑里想的代码如下:

1
2
3
#!/bin/sh
cd /var/git/web3/etc/puppet
/usr/bin/git pull

用这个代码在 git push ssh://git@ownlinux.org:/opt/foo.git 之后,发现远程服务器上的 /dir/foo 目录下并没有成功 pull 到最新的数据,并且终端上也有报错(remote: fatal: Not a git repository: ‘.’)。 后面发现 git 的钩子在运行的时候会调用 GIT_DIR 这个环境变量,而不是PWD 这个。所以在 git pull 的时候提示 Not a git repository: ‘.’ ,其中 “.” 正是 GIT_DIR 这个环境变量的值。

钩子的代码改成下面的之后,运行正常了:

1
2
3
4
#!/bin/sh
unset $(git rev-parse --local-env-vars)
cd /var/git/web3/etc/puppet
/usr/bin/git pull

参考文章:

Bottle + UWSGI + Nginx Quickstart

Customizing Git - Git Hooks

Git Hooks

git 系统中 post-receive 钩子不能正常执行 git pull 解决方法

git钩子 自动更新服务器上版本库

uWSGI参考资料(1.0版本的配置选项列表)

Nginx+uWSGI+bottle 在Linux上部署

Comments !

blogroll

social