【问题标题】:Simplified/PHP/CGI alike django application deployment简化/PHP/CGI 类似 django 应用程序部署
【发布时间】:2017-05-22 19:40:04
【问题描述】:

这是关于什么的

我正在寻找一种方法来简化 django 应用程序在我的服务器上的部署。目前我为每个应用程序使用一个 uWSGI 实例。每当我将新项目上传到我的 www-root-folder 时,我都不想弄乱配置文件。相反,我正在寻找一个更像 php 的解决方案,在那里我可以将项目文件夹上传到我的 www-root 并通过 nginx-> uWSGI 或 nginx-> Gunicorn “自动”使用它,而无需修改配置文件。此外,最好不要为每个应用程序都有一个进程,这样我就不会浪费内存(因为我一次从不使用多个应用程序)

当前状态

我发现,uWSGI 的emperor mode for django applicationsmagic variables 结合使用可能有效。但是在我的配置中,只有一个 django 应用程序的设置会被加载并保持加载,因此没有其他应用程序可以启动。

来自uwsgi.conf.template

[uwsgi]
master             =  true
socket             =  :8000
master             =  true
reuse-port         =  true
reload-os-env      =  true
vaccuum            =  true
logto              =  /var/log/uwsgi-%n.log
manage-script-name =  true
chdir              =  /usr/local/www/%n
mount              =  /%n=%n/wsgi.py

来自nginx.conf

location ~ ^/(.+)/(.+?)$
{
   include uwsgi_params;
   uwsgi_pass 10.0.0.106:8000;
   uwsgi_param UWSGI_SCRIPT $1.wsgi;
   uwsgi_param SCRIPT_NAME /$1;
   uwsgi_param UWSGI_CHDIR /usr/local/www/$1;
   uwsgi_param PATH_INFO "/$2"; # strip path
 }


 location ~ ^/(.+)/$
 {
   include uwsgi_params;
   uwsgi_pass 10.0.0.106:8000;
   uwsgi_param UWSGI_SCRIPT $1.wsgi;
   uwsgi_param SCRIPT_NAME $1;
   # uwsgi_param UWSGI_APPID /$1;
   uwsgi_param DJANGO_SETTINGS_MODULE $1.settings;
   uwsgi_param UWSGI_CHDIR /usr/local/www/$1;
   uwsgi_param PATH_INFO '';
 }

【问题讨论】:

    标签: python django nginx deployment uwsgi


    【解决方案1】:

    又折腾了一天,我终于找到了一个可行的解决方案。这不是最终的解决方案,但它现在有效,每当我再次改进此配置时,我都会尝试更新此答案。

    基本配置

    这在某种程度上接近于在documentation 中可以找到的内容。不过,我发现让它以这种方式工作有点困难。

    nginx.conf

    server
    {
      server_name test.example.com;
      listen [::]:80;
    
      location ~ ^/(.+)/static/(.+)$
      { alias /usr/local/www/$1/static/$2; }
    
      location ~ ^/(.+)/media/(.+)$
      { alias /usr/local/www/$1/media/$2; }
    
      location ~ ^/(.*?)/
      {
        uwsgi_pass unix:///var/run/uwsgi/$1.sock;
        include uwsgi_params;        
      }
    }
    

    /usr/local/www/uwsgi.skel

    [uwsgi]
    master             =  true
    socket             =  /var/run/uwsgi/%c.sock
    reuse-port         =  true
    master             =  true
    reload-os-env      =  true
    vaccuum            =  true
    logto              =  /var/log/uwsgi/%c.log
    manage-script-name =  true
    chdir              =  /usr/local/www/%c
    touch-reload       =  /usr/local/www/%c/%c
    wsgi-file          =  %c/wsgi.py
    mount              =  /%c=%c/wsgi.py
    static-map         =  /static=/usr/local/www/%c/static
    static-map         =  /media=/usr/local/www/%c/media
    unenv              =  DJANGO_SETTINGS_MODULE
    unenv              =  DJANGO_SETTINGS
    wsgi-env-behaviour =  holy
    print              =  we are using %c
    

    我们必须为套接字和日志文件创建所需的文件夹,并注意必要的权限(另见下文)。另请注意,/var/run/ 可能无法在您的操作系统上重新启动后继续存在,因此另一个文件夹可能更适合:

    chmod -R www:www /usr/local/www
    mkdir /var/log/uwsgi/
    chmod -R www:www /var/log/uwsgi/
    mkdir /var/run/uwsgi/
    chmod -R www:www /var/run/uwsgi/
    

    正在启动 uWSGI 主实例...

    我们现在可以在皇帝模式下启动 uwsgi 进程,即使是在emperor-tyrant 模式下:

    uwsgi --emperor 'glob:///usr/local/www/*/uwsgi.ini' --emperor-nofollow --emperor-tyrant \
    --master --thunder-lock --enable-threads
    

    这是我使用的一个技巧:glob 将尝试从/usr/local/www/ 下的每个目录中吸入一个名为uwsgi.ini 的文件。它可能是一个单独的文件,但我只是从上面链接了 skel 文件 (这满足了我不必编辑配置文件的要求)

    cd /usr/local/www/django-app1/
    ln -s ../uwsgi.skel uwsgi.ini
    

    这也很方便,因为最近版本的 GIT 也支持符号链接,因此我的开发机器上的符号链接可以在 uwsgi.skel 文件中具有其他值(例如,不是 /usr/local/www 而是 /var/www/

    关于权限和“皇帝-暴君”模式的一句话......

    皇帝-暴君模式将使uWSGI产生不同用户拥有的进程。哪个用户取决于 uwsgi.ini 文件的权限。 uWSGI 进程然后放弃其权限并在该文件所属的用户名下运行。我还不需要该功能,但如果您尝试设置专业的托管平台,您将需要它。为此,请记住,nginx 必须具有足够的权限来读取和写入生成的套接字文件,并且/var/run/uwsgi/ 也必须对所有这些用户都是可写的。

    设置虚拟环境

    在大约一年没有出现任何问题后,我发现我的一个网站处于非运营状态。事实证明,这是由于向 python3 移动的更新。简而言之:我不得不摆弄一下,因为为其中一个站点设置虚拟环境并不是那么简单,因为在将virtualenv = 添加到我的uwsgi.ini 后,我总是收到No module named site 错误。我的新 ini 文件现在看起来像这样:

    /usr/local/www/project/uwsgi.ini

    [uwsgi]
    master             =  true
    socket             =  /var/run/uwsgi/%c.sock
    reuse-port         =  true
    reload-os-env      =  true
    vaccuum            =  true
    manage-script-name =  true
    
    logto              =  /var/log/uwsgi/%c.log
    virtualenv         =  /usr/local/www/katalogpro/venv/
    chdir              =  /usr/local/www/%c
    touch-reload       =  /usr/local/www/%c/%c
    
    mount              =  /%c=%c/wsgi.py
    static-map         =  /static=/usr/local/www/%c/static
    static-map         =  /media=/usr/local/www/%c/media
    print              =  we are using %c
    
    # set cheaper algorithm to use, if not set default will be used
    cheaper-algo     = backlog
    cheaper-overload = 4
    cheaper-idle     = 1
    cheaper-initial  = 0
    

    请注意,它变得更容易了,因为其中的设置更少。可以进一步调整它并使用配置为.skel-configuration 和 if 语句,如果有的话,它会自动添加一个 virtualenv。现在它又开始工作了,我很高兴。

    【讨论】:

    • 这个设置运行了大约半年,结果非常好用
    猜你喜欢
    • 2010-12-18
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 2017-01-24
    • 2018-10-18
    • 2017-12-01
    相关资源
    最近更新 更多