问题描述
这是一个广泛的问题,但我想得到一个规范的答案.我一直在尝试使用 gunicorn 和 nginx 在 Django 中部署一个站点.在阅读了大量教程后,我已经成功了,但我不能确定我遵循的步骤是否足以运行一个网站而不会出现问题,或者可能有更好的方法来做到这一点.这种不确定性令人讨厌.
This is a broad question but I'd like to get a canonical answer. I have been trying to deploy a site using gunicorn and nginx in Django. After reading tons of tutorials I have been successful but I can't be sure that the steps I followed are good enough to run a site without problems or maybe there are better ways to do it. That uncertainty is annoying.
这就是为什么我要为新手寻找一个非常详细且解释清楚的答案.我不想解释太多我知道的和我不知道的,因为这可能会使答案有些偏差,而其他人可能会在较小程度上从您的答案中受益.但是,我希望提到的一些事情是:
That's why I'm looking for a very detailed and well explained answer for newbies. I don't want to explain too much what I know and what I don't know since this could skew the answers a bit and other people could benefit to a lesser degree from your answers. However, some things I'd like to see mentioned are:
您认为哪种设置"效果最好?我使用了 virtualenv 并将我的 Django 项目移到了这个环境中,但是我看到了另一个设置,其中有一个用于虚拟环境的文件夹和其他用于项目的文件夹.
What "setup" have you seen work best? I used virtualenv and moved my Django project inside this environment, however I have seen another setups where there is a folder for virtual environments and other for projects.
如何设置允许在单个服务器中托管多个站点的方式?
How can I setup things in a way that allows several sites to be hosted in a single server?
为什么有些人建议使用 gunicorn_django -b 0.0.0.0:8000
而其他人建议使用 gunicorn_django -b 127.0.0.1:8000
?我在 Amazon EC2 实例中测试了后者,但它无法正常工作,而前者可以正常工作.
Why some people suggest using gunicorn_django -b 0.0.0.0:8000
and others suggest gunicorn_django -b 127.0.0.1:8000
? I tested the latter in an Amazon EC2 instance but it didn't work while the former worked without problem.
nginx 配置文件背后的逻辑是什么?有很多教程使用截然不同的配置文件,我很困惑哪一个更好.例如,有些人使用别名/path/to/static/folder
和其他人root/path/to/static/folder
.也许你可以分享你喜欢的配置文件.
What is the logic behind the config file of nginx? There are so many tutorials using drastically different configuration files that I'm confused on which one is better. For example, some people use alias /path/to/static/folder
and others root /path/to/static/folder
. Maybe you can share your preferred configuration file.
为什么我们要在 /etc/nginx
中的 site-available
和 sites-enabled
之间创建符号链接?
Why do we create a symlink between site-available
and sites-enabled
in /etc/nginx
?
一些最佳实践一如既往地受欢迎:-)
Some best practices are as always welcomed :-)
谢谢
推荐答案
virtualenv 是一种隔离 Python 环境的方法;因此,它在部署中的作用不大——但是在开发和测试期间,如果不强烈推荐,它是必需的.
virtualenv is a way to isolate Python environments; as such, it doesn't have a large part to play at deployment - however during development and testing it is a requirement if not highly recommended.
您将从 virtualenv 获得的价值是它允许您确保为应用程序安装了正确版本的库.因此,将虚拟环境本身放在何处并不重要.请确保不要将其作为源代码版本控制系统的一部分.
The value you would get from virtualenv is that it allows you to make sure that the correct versions of libraries are installed for the application. So it doesn't matter where you stick the virtual envrionment itself. Just make sure you don't include it as part of the source code versioning system.
文件系统布局并不重要.您将看到许多文章颂扬目录布局的优点,甚至可以将其作为起点进行克隆的骨架项目.我觉得这更多是个人喜好而不是硬性要求.当然,它很好;但是除非您知道原因,否则它不会为您的部署过程增加任何价值 - 所以不要这样做,因为某些博客推荐它,除非它对您的场景有意义.例如 - 如果您没有属于部署工作流程的私有 PyPi 服务器,则无需创建 setup.py
文件.
The file system layout is not critical. You will see lots of articles extolling the virtues of directory layouts and even skeleton projects that you can clone as a starting point. I feel this is more of a personal preference than a hard requirement. Sure its nice to have; but unless you know why, it doesn't add any value to your deployment process - so don't do it because some blog recommends it unless it makes sense for your scenario. For example - no need to create a setup.py
file if you don't have a private PyPi server that is part of your deployment workflow.
如何以允许托管多个站点的方式进行设置在单个服务器中?
进行多个站点设置需要做两件事:
There are two things you need to do multiple site setups:
- 在端口 80 和/或端口 443(如果您有 SSL)上侦听公共 IP 的服务器.
- 一堆运行实际 django 源代码的进程".
人们将 nginx 用于 #1,因为它是一个非常快的代理,并且没有像 Apache 这样的综合服务器的开销.如果您对 Apache 感到满意,您可以自由使用它.没有对于多个站点,使用nginx"的要求;您只需要一个侦听该端口的服务,知道如何重定向(代理)到您运行实际 django 代码的进程.
People use nginx for #1 because its a very fast proxy and it doesn't come with the overhead of a comprehensive server like Apache. You are free to use Apache if you are comfortable with it. There is no requirement that "for mulitple sites, use nginx"; you just need a service that is listening on that port, knows how to redirect (proxy) to your processes running the actual django code.
对于#2,有几种方法可以启动这些过程.gevent/uwsgi 是最受欢迎的.这里唯一要记住的是不要在生产中使用 runserver.
For #2 there are a few ways to start these processes. gevent/uwsgi are the most popular ones. The only thing to remember here is do not use runserver in production.
这些是绝对的最低要求.通常人们会添加某种进程管理器来控制所有运行的django 服务器"(#2).在这里你会看到 upstart
和 supervisor
提到.我更喜欢主管,因为它不需要接管整个系统(与新贵不同).但是,再次重申 - 这不是硬性要求.您可以完美地运行一堆 screen
会话并将它们分离.缺点是,如果您的服务器重新启动,您将不得不重新启动屏幕会话.
Those are the absolute minimum requirements. Typically people add some sort of process manager to control all the "django servers" (#2) running. Here you'll see upstart
and supervisor
mentioned. I prefer supervisor as it doesn't need to take over the entire system (unlike upstart). However, again - this is not a hard requirement. You could perfectly run a bunch of screen
sessions and detatch them. The downside is, should your server restart, you would have to relaunch the screen sessions.
个人建议:
- #1 的 Nginx
- 在 uwsgi 和 gunicorn 之间进行选择 - 我使用 uwsgi.
- supervisor 用于管理后端流程.
- 您托管的每个应用程序的单独系统帐户(用户).
我推荐 #4 的原因是隔离权限;再次强调,不是必须的.
The reason I recommend #4 is to isolate permissions; again, not a requirement.
为什么有些人建议使用 gunicorn_django -b 0.0.0.0:8000 和其他人建议 gunicorn_django -b 127.0.0.1:8000?我测试了后者在 Amazon EC2 实例中,但在前者工作时它不起作用没有问题.
0.0.0.0
表示所有 IP 地址"——它是一个元地址(即占位符地址).127.0.0.1
是一个保留地址,始终指向本地机器.这就是为什么它被称为本地主机".只有在同一系统上运行的进程才能访问它.
0.0.0.0
means "all IP addresses" - its a meta address (that is, a placeholder address). 127.0.0.1
is a reserved address that always points to the local machine. That is why its called "localhost". It is only reachable to processes running on the same system.
通常情况下,您让前端服务器(上面列表中的#1)监听公共 IP 地址.您应该将服务器明确绑定到一个IP地址.
Typically you have the front end server (#1 in the list above) listening on the public IP address. You should explicitly bind the server to one IP address.
然而,如果由于某种原因你使用 DHCP 或者你不知道 IP 地址是什么(例如,它是一个新配置的系统),你可以告诉 nginx/apache/任何其他进程绑定到 0.0.0.0.这应该是一个临时权宜之计.
However, if for some reason you are on DHCP or you don't know what the IP address will be (for example, its a newly provisioned system), you can tell nginx/apache/any other process to bind to 0.0.0.0
. This should be a temporary stop-gap measure.
对于生产服务器,您将拥有一个静态 IP.如果您有动态 IP (DHCP),那么您可以留在 0.0.0.0
.不过,您的生产机器很少有 DHCP.
For production servers you'll have a static IP. If you have a dynamic IP (DHCP), then you can leave in 0.0.0.0
. It is very rare that you'll have DHCP for your production machines though.
在生产中不推荐将gunicorn/uwsgi绑定到这个地址.如果您将后端进程 (gunicorn/uwsgi) 绑定到 0.0.0.0
,它可能会直接"访问,绕过前端代理 (nginx/apache/etc);有人可以请求 http://your.public.ip.address:9000/
并直接访问您的应用程序特别是如果您的前端服务器 (nginx) 和您的后端进程 (django/uwsgi/gevent) 在同一台机器上运行.
Binding gunicorn/uwsgi to this address is not recommended in production. If you bind your backend process (gunicorn/uwsgi) to 0.0.0.0
, it may become accessible "directly", bypassing your front-end proxy (nginx/apache/etc); someone could just request http://your.public.ip.address:9000/
and access your application directly especially if your front-end server (nginx) and your back end process (django/uwsgi/gevent) are running on the same machine.
如果你不想运行前端代理服务器的麻烦,你可以自由地做.
You are free to do it if you don't want to have the hassle of running a front-end proxy server though.
nginx的配置文件背后的逻辑是什么?有这么多使用完全不同的配置文件的教程困惑于哪个更好.例如,有些人使用别名/path/to/static/folder"和其他root/path/to/static/folder".也许你可以分享你喜欢的配置文件.
关于 nginx,您应该了解的第一件事是它不是网络服务器,如 Apache 或 IIS.它是一个代理.因此,您会看到不同的术语,例如上游"/下游"和定义的多个服务器".花点时间先看一遍nginx手册.
First thing you should know about nginx is that it is not a webserver like Apache or IIS. It is a proxy. So you'll see different terms like 'upstream'/'downstream' and multiple "servers" being defined. Take some time and go through the nginx manual first.
有很多不同的方式来设置 nginx;但这里是您关于 alias
与 root
问题的一个答案.root
是一个显式指令,它绑定了 nginx 的文档根目录(主目录").这是当您发出不带路径的请求(例如 http://www.example.com/
There are lots of different ways to set up nginx; but here is one answer to your question on alias
vs. root
. root
is an explicit directive that binds the document root (the "home directory") of nginx. This is the directory it will look at when you give a request without a path like http://www.example.com/
alias
表示将名称映射到目录".别名目录可能不是文档根目录的子目录.
alias
means "map a name to a directory". Aliased directories may not be a sub directory of the document root.
为什么我们要在站点可用和站点启用之间创建符号链接/etc/nginx?
这是 debian(以及类似 debian 的系统,如 ubuntu)所独有的.sites-available
列出系统上所有虚拟主机/站点的配置文件.从 sites-enabled
到 sites-available
的符号链接激活"该站点或虚拟主机.这是一种分离配置文件并轻松启用/禁用主机的方法.
This is something unique to debian (and debian-like systems like ubuntu). sites-available
lists configuration files for all the virtual hosts/sites on the system. A symlink from sites-enabled
to sites-available
"activates" that site or virtual host. It is a way to separate configuration files and easily enable/disable hosts.
这篇关于使用 gunicorn 和 nginx 部署 Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!