简化/ PHP / CGI相似的django应用程序部署

时间:2017-01-08 12:48:49

标签: python django nginx deployment uwsgi

这是什么

我正在寻找在我的服务器上简化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 '';
 }

1 个答案:

答案 0 :(得分:0)

在摆弄另一天之后,我达到了一个有效的解决方案。它不是最终的解决方案,但它现在可以工作,每当我再次改进这个配置时,我都会尝试更新这个答案。

基本配置

这在某种程度上接近于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会尝试从uwsgi.ini下的每个目录中吸取一个名为/usr/local/www/的文件。它可能是一个单独的文件,但我只是链接了上面的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。简而言之:我不得不改变一下,因为为其中一个网站设置虚拟环境并不是一件容易的事,因为我在向{{1} No module named site添加virtualenv =后总是出现uwsgi.ini错误}}。我的新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 - 配置if语句,如果有,则自动添加virtualenv。现在它再次运作,我很高兴。