Django 可以单独在 Gunicorn 上运行(没有 Apache 或 nginx)吗?

Posted

技术标签:

【中文标题】Django 可以单独在 Gunicorn 上运行(没有 Apache 或 nginx)吗?【英文标题】:Can Django run on Gunicorn alone (no Apache or nginx)? 【发布时间】:2012-06-07 09:38:49 【问题描述】:

我几乎尝试了网络上的所有 django + nginx 教程,但我无法在屏幕上显示图像文件。这始终是老故事 - 404 页面未找到。网页加载正常,但我的 /static/ 文件夹中的 django.png 没有。不确定是 settings.py 还是 nginx 的问题。

我对此感到非常沮丧,以至于我拒绝看另一个“如何获得 nginx/django 教程”。如果我在不久的将来部署一个网站,Gunicorn 是否足以在不使用 Apache 或 nginx 的情况下运行 Django 站点并同时提供静态文件?首先拥有反向代理有很大的好处吗?

【问题讨论】:

【参考方案1】:

是的。 Gunicorn 也可以为您提供静态服务。

如果一切都失败了,让 django 为你做这件事(虽然,这是在沮丧之前的最后手段。)为此,你只需要添加另一个 url 模式,如下所示:

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

虽然 django 提供静态服务总比不提供服务要好,但值得将其委托给针对 nginx 进行优化的服务器。

我建议首先在不同的端口上运行 nginx,然后更改 django STATIC_URL 设置以包含该端口(在您确认该端口服务于静态之后)。 - 这样做就像从 nginx 文件夹中对 MEDIA_ROOT 进行 simlink 一样简单。

如果你仍然使用 nginx,最好代理所有使用它的请求,并且只将 django 请求传递给 gunicorn。所有这些都需要添加一个conf 文件来相应地告诉 nginx。

我可以看出它是如何让那些开始并尝试一次完成所有(代理请求、服务静态、配置 nginx)的人感到困惑的。一个一个试试。从独角兽那里获取媒体;然后从 nginx 提供它,然后最终也拥有 nginx 代理。但是,在您将应用程序投入生产之前,请完成所有这些操作。我已经看到这种方法增加了理解并减少了挫败感。

【讨论】:

一次尝试一个的好建议。谢谢。 如果我的服务器只是做REST API,没有静态文件,没有负载均衡,还有什么理由在前面还有nginx @FrozenFlame 请参阅以下 Mark Lavin 的答案。基本上 Gunicorn 本身就容易受到 DoS 攻击。【参考方案2】:

Gunicorn 文档指出,如果没有代理缓冲慢速客户端,默认工作线程很容易受到拒绝服务攻击:http://gunicorn.org/deploy.html

尽管有许多 HTTP 代理可用,但我们强烈建议 你使用 Nginx。如果您选择另一个代理服务器,您需要 确保在使用默认 Gunicorn 时缓冲慢速客户端 工作人员。如果没有这种缓冲 Gunicorn 将很容易受到 拒绝服务攻击。您可以使用 slowloris 检查您的 代理行为正常。

使用 gevent 或 tornado 等异步工作器之一时可能不是这种情况。

【讨论】:

【参考方案3】:

如果您已经在使用亚马逊网络服务,您可以使用 s3 存储桶来托管您的静态内容,并使用 gunicorn(或任何您想要的)将您的应用部署到 ec2。这样,您根本不必担心设置自己的静态文件服务器。

【讨论】:

【参考方案4】:

我推荐在前面使用 Nginx 有几个原因:

gunicorn 关闭时,可以轻松实现维护或内部服务器错误页面。这意味着,如果您的应用程序服务器未运行,您将始终需要响应。 正如 Gunicorn doc 建议的那样,不会检测到诸如 DOS 之类的 http 攻击。 您可能希望稍后实施自己的负载平衡策略。随着项目规模的扩大,这对于发布工程来说将变得更加重要。就个人而言,我发现 AWS ELB 有点不可靠,我正在考虑。

更新

另外,请参阅 Gunicorn 开发人员写得很好的回答:

Why do I need Nginx and something like Gunicorn?

【讨论】:

gunicorn 宕机时如何显示错误页面? 您可以向 nginx 添加文件是否存在检查:serverfault.com/questions/310819/… 也可以使用 bash 快捷方式来触摸/rm 该文件。【参考方案5】:

我使用 Werkzeug 中间件制作。不漂亮,也不像使用 nginx 服务器那样高效,但可以完成工作:

在 settings.py 上设置 STATIC_ROOT

# project/settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__)))
STATIC_ROOT = BASE_DIR+'/static-collected'

告诉 Werkzeug 提供此文件夹中的文件

# project/wsgi.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

(...)
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
(...)

import os
from werkzeug.wsgi import SharedDataMiddleware
print 'Installing WSGI static files server middleware'
application = SharedDataMiddleware(application, 
    '/static': os.path.join(BASE_DIR, 'static-collected'),
)

当 DEBUG=True 时,Django 提供文件。当 DEBUG=False 时,Werkzeug 从静态收集的文件夹中提供文件。您需要在使用 DEBUG=False 的服务器上运行 collectstatic 才能使其工作。

Obs:出于某种原因,Werkzeug 为未找到的文件给出 500,而不是 404。这很奇怪,但仍然有效。如果您知道原因,请发表评论。

【讨论】:

以上是关于Django 可以单独在 Gunicorn 上运行(没有 Apache 或 nginx)吗?的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 Foreman 在 Gunicorn 上本地运行 Django 应用程序

如何运行多个Django App Gunicorn systemd?

django 和 gunicorn 在 docker 容器内运行时,无法在 ec2 上使用 nginx 提供静态文件

如何调试使用 whitenoise、gunicorn 和 heroku 服务的 django 静态文件?

在 gunicorn 和 Tornado 上使用 Django 项目

通过 Gunicorn/Nginx 使用 Django 的站点框架运行多个站点