使用nginx和uwsgi在Linux上部署falcon¶
nginx是一个功能强大的Web服务器和反向代理,uwsgi是一个快速且高度可配置的wsgi应用服务器。nginx和uwsgi一起创建了一个一二冲头的速度和功能,将满足大多数应用。此外,此堆栈为水平可伸缩和高可用性(HA)生产环境提供了构建块,下面的配置只是一个起点。
本指南仅提供部署到Linux环境的说明。但是,通过一些努力,您应该能够将此配置适应其他操作系统,如OpenBSD。
以其他用户身份运行应用程序¶
最好是以不同的操作系统用户身份执行应用程序,而不是以拥有应用程序源代码的用户身份执行。应用程序用户应该 NOT 对您的源具有写入权限。这降低了有人通过您可能定义的上载端点将恶意Python文件写入您的源目录的可能性;当您的应用程序重新启动时,恶意文件将被加载,并继续导致任意数量的Bad Things™发生。
$ useradd myproject --create-home
$ useradd myproject-runner --no-create-home
切换到项目用户(myproject)并使用主目录作为应用程序环境是很有帮助的。
如果您在远程服务器上工作,请切换到MyProject用户并下拉应用程序的源代码。
$ git clone git@github.com/myorg/myproject.git /home/myproject/src
备注
您可以使用tarball、zip文件、scp或任何其他方法将源文件放到服务器上。
接下来,创建一个可用于安装依赖项的虚拟环境。
$ python3 -m venv /home/myproject/venv
然后安装依赖项。
$ /home/myproject/venv/bin/pip install -r /home/myproject/src/requirements.txt
$ /home/myproject/venv/bin/pip install -e /home/myproject/src
$ /home/myproject/venv/bin/pip install uwsgi
备注
创建虚拟环境的确切命令可能会因所使用的Python版本和操作系统的不同而有所不同。最后,应用程序需要在/home/myproject/venv中安装virtualenv,并安装项目依赖项。使用 pip
虚拟环境中的二进制文件 source venv/bin/activate
或者使用完整路径。
准备您的服务申请¶
出于本教程的目的,我们假设您已经实现了一种配置应用程序的方法,例如使用 create_app()
函数或模块级脚本。此函数或脚本的作用是提供 falcon.App
,它实现了标准的WSGI Callable接口。
你需要暴露 falcon.App
以某种方式举例,以便Uwsgi可以找到它。对于本教程,我们建议创建 wsgi.py
文件。修改以下示例文件的逻辑以正确配置应用程序。确保公开一个名为 application
分配给您的 falcon.App
实例。
import os
import myproject
# Replace with your app's method of configuration
config = myproject.get_config(os.environ['MYPROJECT_CONFIG'])
# uWSGI will look for this variable
application = myproject.create_app(config)
请注意,在上面的示例中,wsgi可调用文件只是简单地分配给一个变量, application
而不是被传递到一个自托管的wsgi服务器,例如 wsgiref.simple_server.make_server .在您的 wsgi.py
文件将呈现意外结果。
在UWSGI后面部署Falcon¶
与您的 wsgi.py
文件就位,是时候配置UWSGI了。首先创建一个简单的 uwsgi.ini
文件。通常,您不应该将此文件提交到源代码管理;它应该由部署工具链根据目标环境(CPU数量等)从模板生成。
执行此配置时,将创建一个由您的 wsgi.py
文件和监听 127.0.0.1:8080
.
[uwsgi]
master = 1
vacuum = true
socket = 127.0.0.1:8080
enable-threads = true
thunder-lock = true
threads = 2
processes = 2
virtualenv = /home/myproject/venv
wsgi-file = /home/myproject/src/wsgi.py
chdir = /home/myproject/src
uid = myproject-runner
gid = myproject-runner
备注
线程与进程
在决定如何管理实际运行Python代码的进程时,需要考虑许多问题。您通常是CPU绑定还是IO绑定?您的应用程序线程安全吗?你有多少个CPU?你用的是什么系统?是否需要进程内缓存?
这里介绍的配置同时支持线程和进程。但是,您必须进行一些实验和研究,以了解您的应用程序的独特需求,然后相应地定制您的uwsgi配置。一般来说,uwsgi足够灵活,可以支持大多数类型的应用程序。
备注
TCP与Unix套接字
nginx和uwsgi可以通过普通TCP(使用IP地址)或Unix套接字(使用套接字文件)进行通信。TCP套接字更容易设置,通常用于简单的部署。如果您想更好地控制哪些进程、用户或组可以访问uwsgi应用程序,或者您正在寻找一点速度提升,请考虑使用unix套接字。uwsgi可以自动删除权限 chmod-socket
和切换用户 chown-socket
.
这个 uid
和 gid
如上所示,设置对于确保部署的安全至关重要。这些值控制服务器将用于执行应用程序的操作系统级用户和组。指定的OS用户和组不应具有对源目录的写入权限。在这种情况下,我们使用 myproject-runner 以前为此目的创建的用户。
现在您可以这样启动Uwsgi:
$ /home/myproject/venv/bin/uwsgi -c uwsgi.ini
如果一切顺利,您应该看到如下情况:
*** Operational MODE: preforking+threaded ***
...
*** uWSGI is running in multiple interpreter mode ***
...
spawned uWSGI master process (pid: 91828)
spawned uWSGI worker 1 (pid: 91866, cores: 2)
spawned uWSGI worker 2 (pid: 91867, cores: 2)
备注
注意uwsgi日志始终是一个好主意,因为它们将包含异常和来自应用程序的其他信息,这些信息有助于揭示意外行为。
连接nginx和uwsgi¶
虽然Uwsgi可以直接为HTTP请求提供服务,但使用反向代理(如nginx)可以帮助卸载TLS协商、静态文件服务等。
nginx本机支持 the uwsgi protocol ,以便有效地将请求代理到uwsgi。按照nginx的说法,我们将创建一个“上游”并将其(通过TCP套接字)引导到我们现在运行的uwsgi应用程序。
在继续之前,根据 the instructions for your platform .
然后,创建一个nginx conf文件,如下所示:
server {
listen 80;
server_name myproject.com;
access_log /var/log/nginx/myproject-access.log;
error_log /var/log/nginx/myproject-error.log warn;
location / {
uwsgi_pass 127.0.0.1:8080
include uwsgi_params;
}
}
最后,启动(或重启)nginx:
$ sudo service start nginx
现在应该有一个有效的应用程序了。如果应用程序没有启动,请检查Uwsgi和nginx日志中的错误。
进一步考虑¶
我们没有解释如何为nginx配置tls(https),将其作为一个练习留给读者。但是,我们确实建议使用let's encrypt,它提供免费的短期证书和自动续订。访问 Let’s Encrypt site 了解如何将他们的服务直接与nginx集成。
除了设置nginx和uwsgi来运行应用程序外,您当然还需要部署数据库服务器或应用程序所需的任何其他服务。由于在这一领域有多种选择和考虑,我们选择不在本指南中包括辅助服务。但是,Falcon社区总是乐于帮助解决部署问题,因此 please don't hesitate to ask .