这是一个广泛的问题,但我想得到一个规范的答案 . 我一直在尝试在Django中使用gunicorn和nginx部署一个站点 . 在阅读了大量的教程后,我已经取得了成功,但我无法确定我所遵循的步骤是否足以运行一个没有问题的站点,或者可能有更好的方法来实现它 . 这种不确定性很烦人 .
这就是为什么我正在为新手寻找一个非常详细且解释清楚的答案 . 我不想过多地解释我所知道的和我不知道的事情,因为这可能会使答案有所偏差,而其他人可能会从你的答案中获益较少 . 但是,我想提到的一些事情是:
-
你见过什么"setup"最好?我使用了virtualenv并将我的Django项目移到了这个环境中,但是我看到了另一个设置,其中有一个虚拟环境文件夹和其他项目文件夹 .
-
如何以允许多个站点托管在单个服务器中的方式设置内容?
-
为什么有些人建议使用
gunicorn_django -b 0.0.0.0:8000
而其他人建议gunicorn_django -b 127.0.0.1:8000
?我在Amazon EC2实例中对后者进行了测试,但是当前者工作没有问题时它没有工作 . -
nginx配置文件背后的逻辑是什么?有很多教程使用截然不同的配置文件,我很困惑哪一个更好 . 例如,有些人使用
alias /path/to/static/folder
和其他人root /path/to/static/folder
. 也许您可以共享首选配置文件 . -
为什么我们在
/etc/nginx
中的site-available
和sites-enabled
之间创建一个符号链接? -
一些最佳实践一如既往地欢迎:-)
谢谢
4 回答
好吧,就你在问题中提出的最佳实践而言,我无法帮助分享一个对我来说有奇迹的工具!我自己曾经在几个网站的gunicorn,nginx,supervisorD的几个配置文件中感到困惑!但我渴望以某种方式自动化整个过程,以便我可以对我的应用程序/站点进行更改并立即进行部署 . 它的名字是django-fagungis . 您可以使用Django Deployment automation here找到我的体验详情 . 我刚配置了一个fabfile.py ONCE(django-fagungis使用fabric来自动化整个过程,并在你的远程服务器上创建一个virtualenv,它可以管理单个服务器上托管的几个站点的依赖关系 . 它使用nginx,gunicorn和supervisorD来处理Django项目/站点部署)和django-fagungis从bitbucket(我用于颠覆)克隆我的最新项目并将其部署在我的远程服务器上,我只需要在本地机器的shell上输入三个命令即可! !对我来说,这已经证明是Django部署的最佳和最轻松的自由练习 .
检查这是否为Django项目所需的最小gunicorn和nginx配置 . http://agiliq.com/blog/2013/08/minimal-nginx-and-gunicorn-configuration-for-djang/
virtualenv是一种隔离Python环境的方法;因此,它在部署中没有很大的作用 - 但是在开发和测试期间,如果不是强烈推荐则是必需的 .
您将从virtualenv获得的值是,它允许您确保为应用程序安装了正确版本的库 . 所以你坚持虚拟环境本身并不重要 . 请确保您不将其作为源代码版本控制系统的一部分包含在内 .
文件系统布局并不重要 . 您将看到许多文章赞美目录布局的优点,甚至可以克隆的骨架项目作为起点 . 我觉得这更像是个人偏好而不是硬性要求 . 当然很高兴;但除非你知道原因,否则它不会这样做,因为有些博客会推荐它,除非它对你的场景有意义 . 例如 - 如果您没有属于部署工作流的私有PyPi服务器,则无需创建
setup.py
文件 .您需要做两件事来进行多个站点设置:
如果您有SSL,则在端口80和/或端口443上侦听公共IP的服务器 .
正在运行实际django源代码的一堆"processes" .
人们使用nginx作为#1,因为它是一个非常快速的代理,并没有像Apache这样的综合服务器的开销 . 如果您对它感到满意,可以自由使用Apache . 没有要求“为多个站点,使用nginx”;您只需要一个正在侦听该端口的服务,知道如何将(代理)重定向到运行实际django代码的进程 .
对于#2,有几种方法可以启动这些过程 . gevent / uwsgi是最受欢迎的 . 这里唯一要记住的是不要在 生产环境 中使用runserver .
这些是绝对最低要求 . 通常人们会添加某种流程管理器来控制所有运行的#1283916_(#2) . 在这里你会看到提到upstart和supervisor . 我更喜欢主管,因为它不需要接管整个系统(不像暴发户) . 然而,再次 - 这不是一个艰难的要求 . 你可以完美地运行一堆screen个会话并解除它们 . 缺点是,如果您的服务器重新启动,您将不得不重新启动屏幕会话 .
我个人会建议:
Nginx为#1
在uwsgi和gunicorn之间选择 - 我使用uwsgi .
supervisor用于管理后端流程 .
您托管的每个应用程序的单个系统帐户(用户) .
我建议#4的原因是隔离权限;再次,不是要求 .
0.0.0.0
表示"all IP addresses" - 它是一个元地址(即占位符地址) .127.0.0.1
是始终指向本地计算机的保留地址 . 这就是为什么它被称为"localhost" . 它只能在同一系统上运行的进程访问 .通常,您有前端服务器(上面列表中的#1)监听公共IP地址 . 您应该将服务器显式绑定到 one IP地址 .
但是,如果由于某种原因您使用的是DHCP或者您不知道IP地址是什么(例如,它是新配置的系统),您可以告诉nginx / apache /任何其他进程绑定到
0.0.0.0
. 这应该是 temporary stop-gap measure .对于 生产环境 服务器,您将拥有静态IP . 如果您有动态IP(DHCP),则可以保留
0.0.0.0
. 但是很少有你的 生产环境 机器可以使用DHCP .在 生产环境 中不建议将gunicorn / uwsgi绑定到此地址 . 如果将后端进程(gunicorn / uwsgi)绑定到
0.0.0.0
,它可能会绕过您的前端代理(nginx / apache / etc)而无法访问"directly";有人可以直接请求http://your.public.ip.address:9000/
并直接访问您的应用程序 especially if your front-end server (nginx) and your back end process (django/uwsgi/gevent) are running on the same machine .如果您不想轻松运行前端代理服务器,则可以自由地执行此操作 .
关于nginx,你应该知道的第一件事是它像Apache或IIS一样_1283933 . 这是一个代理人 . 所以你定义了上游'/'下游'和多个"servers" . 花点时间先阅读nginx手册 .
设置nginx有很多种不同的方法;但是这里是关于
alias
与root
的问题的一个答案 .root
是绑定nginx的文档根目录("home directory")的显式指令 . 这是当你提交没有像http://www.example.com/
这样的路径的请求时它会看到的目录alias
表示"map a name to a directory" . 别名目录可能不是文档根目录的子目录 .这是debian(和像ubuntu一样的类似debian的系统)的独特之处 .
sites-available
列出系统上所有虚拟主机/站点的配置文件 . 从sites-enabled
到sites-available
"activates"该站点或虚拟主机的符号链接 . 这是一种分离配置文件并轻松启用/禁用主机的方法 .我不是部署专家,但会分享我使用gevent部署Django的一些做法(尽管应该类似于gunicorn) .
virtualenv
非常好,因为我不会进入 . 然而,我发现virtualenv-wrapper
(docs)非常有用,特别是当你正在处理许多项目时,因为它允许在不同的virtualenv之间轻松切换 . 这并不适用于部署环境,但是当我需要使用SSH在服务器上进行故障排除时,我发现这非常有用 . 使用它的另一个好处是它管理virtualenv目录,因此减少了手动工作 . Virtualenvs应该是一次性的,以便在遇到版本问题或任何其他安装问题时,您可以转储env并创建一个新的 . 因此,最好不要在virtualenv中包含任何项目代码 . 它应该分开 .至于设置多个站点,
virtualenv
几乎就是答案 . 你应该为每个项目都有一个单独的virutalenv . 只有这一点才能解决许多问题 . 然后在部署时,不同的Python进程将运行不同的站点,这可以避免部署之间出现任何可能的冲突 . 我特别发现在同一服务器上管理多个站点非常有用的一个工具是supervisor
(docs) . 它为启动,停止和重新启动不同的Django实例提供了一个简单的界面 . 也是能够在失败或计算机启动时自动重启进程 . 因此,举例来说,如果引发了一些异常而没有任何异常,整个网站都会崩溃 . 主管将捕获它并将自动重启Django实例 . 以下是示例管理程序(单个进程)配置:对于Nginx,我知道一开始可能会让人不知所措 . 我发现Nginx book非常有用 . 它解释了所有主要的nginx指令 .
在我的nginx安装中,我发现最好的做法是只设置
nginx.conf
文件中的核心配置,然后我有一个单独的文件夹sites
,我保留了我托管的每个站点的nginx配置 . 然后我只在核心配置文件中包含该文件夹中的所有文件 . 我使用指令include sites/+*.conf;
. 这样它只包含sites
文件夹中以+
符号开头的文件 . 这样只需通过文件名我可以控制哪些配置文件被加载 . 因此,如果我想禁用某个站点,我只需要重命名配置文件并重新启动nginx . 在你的问题中不确定你的意思是"symlink between site-available and sites-enabled in /etc/nginx",因为那些是Apache命名的文件夹,但它们完成了与include
指令类似的任务 .对于
root
和alias
指令,它们几乎相同,除非计算它们的根 . 在alias
中,无论在location
中丢弃了什么,而在根中它不是 . 您拥有以下nginx配置的图片:如果用户转到这些URL,那么nginx将尝试在系统的以下位置查找文件:
这是nginx站点的简单配置:
希望这对你有所帮助 .