【问题标题】:Best practice for setting up Flask+uWSGI+nginx [closed]设置 Flask+uWSGI+nginx 的最佳实践 [关闭]
【发布时间】:2014-04-21 09:17:00
【问题描述】:
我正在尝试使用 Flask、uWSGI 和 nginx 的组合来设置我的第一个 Web 服务器。我在运行 Flask 和 uWSGI 组件方面取得了一些成功。我还从各种博客中获得了许多关于如何设置的提示。但是,没有一致性,文章提出了许多不同的设置方法,特别是在涉及文件夹结构、nginx 配置和用户/权限的情况下(我已经尝试了其中的一些建议并且很多确实有效,但我不确定哪个是最好的)。那么有没有一种基本的“最佳实践”方式来设置这个堆栈呢?
【问题讨论】:
标签:
python
nginx
flask
uwsgi
【解决方案1】:
nginx + uwsgi + flask 组成一个强大的堆栈!我将主管添加到组合中并进行如下配置。
- 在主管之外运行 uwsgi 和 nginx 以获得更好的过程控制。然后你可以在启动时启动 supervisor,它会以正确的顺序运行 uwsgi 和 nginx。如果他们死了,它也会聪明地尝试让他们活着。请参阅下面的示例主管配置。
- 如果您在同一主机上运行 nginx 和 uwsgi,请使用 unix 套接字而不是 HTTP。
- 如果您的 Web 服务器正在侦听端口 80,则 nginx 主进程必须以 root 身份运行。我通常在其他端口(如 8080)上运行我的 Web 服务器,并在前面使用负载均衡器来侦听端口 80 并代理到nginx。
- 确保您的 uwsgi 服务器有权读取/写入您选择的套接字文件以及对任何应用程序代码和数据目录的适当权限。
不要太担心您的文件夹结构,尤其是当您使用具有合理默认设置的 Linux 发行版(如 Ubuntu)时。主主管配置文件可以包含来自 /etc/supervisor/conf.d/ 等子目录的文件,以将您的应用程序特定配置与主管核心配置分开。 nginx 也是如此,只有/etc/nginx/sites-enabled。
uwsgi 和 nginx 的示例主管配置:
$ cat /etc/supervisor/conf.d/app.conf
[program:app]
command=/usr/local/bin/uwsgi
--enable-threads
--single-interpreter
--vacuum
--chdir /path/to/app
--uid www-data
--log-syslog
--processes 4
--socket /tmp/app.sock
-w mypython:app
--master
directory=/path/to/app
autostart=true
autorestart=true
priority=999
stopsignal=INT
environment=SOMEVAR=somevalue
[program:nginx]
command=/usr/sbin/nginx
autostart=true
autorestart=true
priority=999
示例 nginx.conf:
$ cat /etc/nginx/sites-enabled/myapp.conf
server {
listen 8080;
client_max_body_size 4G;
server_name localhost;
keepalive_timeout 5;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/app.sock;
}
}
【解决方案2】:
这有两个部分,一个是设置系统本身(我的意思是操作系统及其各种路径/文件系统),第二部分是安装和配置组件。
我将专注于第二部分,我相信这是您问题的症结所在:
nginx 应由操作系统的本机包管理实用程序安装。这将确保正确设置所有权限,并且配置文件位于您(或其他任何人)期望的位置。例如,这意味着在类似 debian 的系统上(如 ubuntu 及其各种表亲),配置在/etc/nginx/,站点通过在/etc/nginx/sites-available/ 中添加文件来配置等等。这也意味着,如果您的操作系统供应商推送更新,它们将由您的打包软件自动安装。
uWSGI 你应该按源安装;因为它的开发周期非常快,uwsgi 的改进将对您的应用程序产生积极影响。安装过程简单,无需特殊权限;除了在系统范围内安装应用程序所需的普通 root/超级用户权限。
您的应用程序的源文件。为此,我强烈建议为每个应用程序创建单独的用户角色并隔离所有权限和所有相关文件(例如,uwsgi 生成的日志文件),以便它们都归同一个用户所有。这样可以确保其他应用程序/用户无法读取错误消息/日志文件,并且一个用户拥有读取/调试与该应用程序相关的所有内容的所有权限,而无需使用 sudo 等工具。
除了上面提到的三点之外,实际上让所有这些组件一起工作是一个标准过程:
在您的应用程序中创建您的 wsgi 进程/处理程序。对于flask,默认的flask应用已经提供了这个接口。
使用您的 wsgi 引擎运行此文件。这是uwsgi 或gunicorn 或类似名称。确保您使用的是二进制协议。
将您的静态文件映射到由您的网络代理服务的位置(这是nginx);并创建一个指向 wsgi 进程期望连接的位置的上游服务器。这可以是端口或管道(取决于您如何设置组件)。
可选使用像supervisor这样的进程管理器来控制wsgi进程,以便它们在系统重新启动时重新启动并且更易于管理。
其他一切都取决于个人喜好(尤其是在文件系统布局方面)。对于大型应用程序,flask 的创建者提供了blueprints,但再次注意他们不赞美任何文件系统/目录布局。
作为任何 Python 包的一般规则,我会推荐你this link。
【解决方案3】:
您要求的不是“最佳实践”,而是“惯例”。不,项目中没有关于路径、权限等的约定。每个系统管理员(或开发人员)都有自己的需求和品味,所以如果您对当前的设置感到满意……那么“任务完成”。没有 uWSGI 大神可以取悦 :) 显然发行版提供的软件包必须有自己的约定,但它们又因发行版而异。