使用gunicorn和nginx部署Django

使用gunicorn和nginx部署Django,django,deployment,nginx,setup-deployment,gunicorn,Django,Deployment,Nginx,Setup Deployment,Gunicorn,这是一个广泛的问题,但我想得到一个规范的答案。我一直在尝试在Django中使用gunicorn和nginx部署一个站点。在阅读了大量教程之后,我已经取得了成功,但我不能确定我所遵循的步骤是否足够好,可以毫无问题地运行一个网站,或者是否有更好的方法来运行它。这种不确定性令人恼火 这就是为什么我要为新手寻找一个非常详细和解释清楚的答案。我不想解释太多我知道的和我不知道的,因为这可能会使答案有点偏斜,而其他人可能会从你的答案中受益较少。然而,我希望看到提到的一些事情是: 你认为什么“设置”最有效?我

这是一个广泛的问题,但我想得到一个规范的答案。我一直在尝试在Django中使用gunicorn和nginx部署一个站点。在阅读了大量教程之后,我已经取得了成功,但我不能确定我所遵循的步骤是否足够好,可以毫无问题地运行一个网站,或者是否有更好的方法来运行它。这种不确定性令人恼火

这就是为什么我要为新手寻找一个非常详细和解释清楚的答案。我不想解释太多我知道的和我不知道的,因为这可能会使答案有点偏斜,而其他人可能会从你的答案中受益较少。然而,我希望看到提到的一些事情是:

  • 你认为什么“设置”最有效?我使用了virtualenv并将我的Django项目移到了这个环境中,但是我看到了另一个设置,其中有一个用于虚拟环境和其他项目的文件夹

  • 如何以允许在一台服务器上托管多个站点的方式进行设置

  • 为什么有些人建议使用
    gunicorn\u django-b0.0.0:8000
    ,而另一些人建议使用
    gunicorn\u django-b127.0.0.1:8000
    ?我在AmazonEC2实例中测试了后者,但它不起作用,而前者工作正常

  • nginx的配置文件背后的逻辑是什么?有太多教程使用完全不同的配置文件,我不知道哪一个更好。例如,有些人使用
    alias/path/to/static/folder
    ,有些人使用
    root/path/to/static/folder
    。也许您可以共享您的首选配置文件

  • 为什么我们要在
    /etc/nginx
    中的
    可用站点
    启用站点
    之间创建一个符号链接

  • 一些最佳实践始终受到欢迎:-)


谢谢

我不是部署专家,但我将与gevent分享我部署Django的一些实践(不过应该与gunicorn类似)

virtualenv
非常棒,原因我将不赘述。然而,我发现
virtualenv wrapper
()非常有用,特别是当您正在处理许多项目时,因为它允许在不同的virtualenv之间轻松切换。这实际上并不适用于部署环境,但是当我确实需要使用SSH在服务器上进行故障排除时,我发现这非常有用。使用它的另一个优点是,它管理virtualenv目录,因此您的手动工作更少。VirtualEnv是一次性的,因此如果您有版本问题或任何其他安装问题,您可以转储env并创建一个新的。因此,最好不要在virtualenv中包含任何项目代码。它应该分开保存

至于设置多个站点,
virtualenv
几乎就是答案。每个项目都应该有一个单独的virutalenv。单凭这一点就可以解决许多问题。然后,在部署时,不同的Python进程将运行不同的站点,从而避免部署之间的任何可能冲突。在管理同一服务器上的多个站点时,我发现一个非常有用的工具是
supervisor
()。它为启动、停止和重新启动不同的Django实例提供了一个简单的界面。它还能够在进程失败或计算机启动时自动重新启动进程。因此,例如,如果引发了某个异常,但没有任何内容捕获它,则整个网站都可能会崩溃。Supervisor将捕获该消息并自动重新启动Django实例。下面是一个示例监控程序(单个进程)配置:

对于Nginx,我知道一开始它可能会让人难以承受。我发现Nginx非常有用。它解释了所有主要的nginx指令

在我的nginx安装中,我发现最好的做法是只在
nginx.conf
文件中设置核心配置,然后我有一个单独的文件夹
sites
,其中保存了我托管的每个站点的nginx配置。然后,我将该文件夹中的所有文件都包含在核心配置文件中。我使用指令
include sites/+*.conf。这样,它只包括
站点
文件夹中以
+
符号开头的文件。这样,我就可以通过文件名控制要加载的配置文件。因此,如果我想禁用某个站点,我只需重命名配置文件并重新启动nginx。不太清楚您在问题中所说的“站点可用和站点在/etc/nginx中启用之间的符号链接”是什么意思,因为这些是Apache命名的文件夹,但它们完成的任务与
include
指令类似

至于
root
alias
指令,除了在计算它们的根的地方,它们几乎是相同的。在
别名中
,中的
位置
中的任何内容都会被删除,而在其根目录中则不会。图像显示您具有以下nginx配置:

location /static {
    alias /some/path/;
}
location /static2 {
    root /some/other/path/;
}
如果用户转到这些URL,nginx将尝试在系统上的以下位置查找文件:

/static/hello/world.pdf => /some/path/hello/world.pdf
/static2/hello/world.pdf => /some/other/path/static2/hello/world.pdf
这是nginx站点的简单配置:

server {
    server_name .foodomain.com;
    listen 80;

    access_log logs/foodomain.log;

    gzip                on;
    gzip_http_version   1.0;
    gzip_comp_level     2;
    gzip_proxied        any;
    gzip_min_length     1100;
    gzip_buffers        16 8k;
    gzip_types          text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    # Set a vary header so downstream proxies don't send cached gzipped content to IE6
    gzip_vary on;

    location / {
        proxy_read_timeout      30s;
        proxy_pass              http://localhost:8000;
        proxy_set_header        Host                 $host;
        proxy_set_header        User-Agent           $http_user_agent;
        proxy_set_header        X-Real-IP            $remote_addr;
    }

    location /media {
        alias   /path/to/media/;
        expires 1y;
    }

    location /static {
        autoindex on;
        expires   1y;
        alias     /path/to/static/;
    }

     location /favicon.ico {
        alias /path/to/favicon.ico;
    }
}
希望这对你有所帮助

你认为什么“设置”最有效?我使用了virtualenv并移动了我的 django项目在这个环境中,但是我看到了另一个 有用于虚拟环境和其他应用程序的文件夹的设置 项目

virtualenv是一种隔离Python环境的方法;因此,它在部署中没有很大的作用——但是在开发和测试过程中,如果不是强烈推荐的话,它也是一项要求

从virtualenv获得的价值在于,它允许您确保为应用程序安装了正确版本的库。因此,将虚拟环境本身放置在何处并不重要。只需确保不将其作为源代码版本控制系统的一部分

文件系统
server {
    server_name .foodomain.com;
    listen 80;

    access_log logs/foodomain.log;

    gzip                on;
    gzip_http_version   1.0;
    gzip_comp_level     2;
    gzip_proxied        any;
    gzip_min_length     1100;
    gzip_buffers        16 8k;
    gzip_types          text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    # Set a vary header so downstream proxies don't send cached gzipped content to IE6
    gzip_vary on;

    location / {
        proxy_read_timeout      30s;
        proxy_pass              http://localhost:8000;
        proxy_set_header        Host                 $host;
        proxy_set_header        User-Agent           $http_user_agent;
        proxy_set_header        X-Real-IP            $remote_addr;
    }

    location /media {
        alias   /path/to/media/;
        expires 1y;
    }

    location /static {
        autoindex on;
        expires   1y;
        alias     /path/to/static/;
    }

     location /favicon.ico {
        alias /path/to/favicon.ico;
    }
}