Supervisor配合uwsgi部署flask应用

这已经是第N次来部署flask应用了, 但是每次都花了不少时间在配置上面, 这里一次性记录下, 备个忘~

写在前面

其实使用uwsgi来部署flask应用在官网上已经有较为详细的文档了, 推荐先读一下.

先解决一些问题:

  • 为何使用uwsgi来部署应用? 方便管理; 较为常见的部署方式; 可配置性较强
  • 为何使用supervisor来管理? 方便管理

下面介绍尝试用它俩部署个最简单的flask应用.

准备

首先请使用pip安装好flask, uwsgi, supervisor. 我们的小应用是这样子的:

test.py
1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

配置uwsgi

uwsgi我们采用master + 多进程 + non-daemon方式来启动我们的应用, 对应的配置文件是像这样子的:

uwsgi.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[uwsgi]

http = 0.0.0.0:8080

## 指定应用目录
chdir = /path/of/test.py

## 配置下访问日志格式
log-format = '%(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) %(msecs)'

need-app = 1
master = 1
processes = 2
umask = 022

module = test:app

这里使用了http, 而非http-socket, 推荐可以阅读下uwsgi的quickstart

编辑好配置文件后, 使用uwsgi --ini uwsgi.ini来看看我们应用是否ok. uwsgi的参数特别多, 推荐使用前阅读一下官方文档.

配置supervisor

使用pip安装的supervisor因为没有默认的配置文件, run起来稍微有点麻烦, 这里提供一个最最简单的可用的配置(用对应发行版的包更好):

supervisord.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[unix_http_server]
file = /home/of/supervisor/etc/supervisord/supervisor.sock

[supervisord]
logfile = /home/of/supervisor/etc/supervisord/log/supervisord.log
loglevel = info
pidfile = /home/of/supervisor/etc/supervisord/supervisord.pid

[supervisorctl]
serverurl = unix:///home/of/supervisor/etc/supervisord/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[include]
files = /home/of/supervisor/etc/supervisord/conf/*.conf

我们把所有supervisor的信息都存放到/home/of/supervisor里面, 然后我们做个软链放到/etc/supervisord.conf(默认配置文件), 避免supervisorctl启动时指定配置文件.

然后启动下supervisord, 顺便看下supervisord.log日志;)

接下来我们要做的就是把各个应用的supervisor配置放到etc/supervisord/conf/下面. 简单配置下test对应的supervisor配置:

test.supervisor.conf
1
2
3
4
5
6
7
8
[program:test]

command = uwsgi --ini /path/of/test.uwsgi.conf
autorestart = true

redirect_stderr = true
stdout_logfile = /path/of/test.log
stopsignal = INT

请注意stopsignal = INT这个配置, 因为supervisor使用 SIGTERM 来停止应用, 而uwsgi则是接手 SIGINT 来停止的, 所以我们需要显示修正下. 更多信息请参考这里

改完之后需要使用supervisorctl reload来让supervisord重新加载配置文件. 可以通过supervisorctl status/stop/restart test分别来查看, 停止, 重启我们的test应用.

最后

到这里整个应用就部署完毕了, 管理起来也蛮方便的. 如果有更细化的需求基本可以通过配置uwsgi和supervisor的配置来实现.

Comments