Что является наиболее распространенным способом настройки статических файлов при отладке и производстве для Django? - PullRequest
4 голосов
/ 06 мая 2011

При разработке приложения Django в режиме отладки я обслуживаю статические файлы, используя следующий код:

if settings.DEBUG:
    urlpatterns += patterns('',
        (r'^m/(?P<path>.*)$', serve, {
            'document_root' : os.path.join(os.path.dirname(__file__), "media")
        })
    )

Я использую nginx в качестве внешнего интерфейса для сервера моих статических файлов в производственном режиме, используя следующую конфигурацию nginx:

  location m/
      {
           root /path/to/folder/media/;
      }

Что кажется неоптимальным, потому что я должен создать папку "m" в каталоге мультимедиа. Мне интересно, как выглядят все остальные файлы конфигурации Django / nginx. В частности, вы можете вырезать и вставить разделы nginx.confg и urls.py (settings.DEBUG == True)

Спасибо.

Ответы [ 2 ]

10 голосов
/ 06 мая 2011

Использование Django 1.3 django.contrib.staticfiles позаботится о том, чтобы обслуживать вас во время разработки. Вам не нужно делать ничего конкретного в urls.py. Я написал небольшое руководство для себя после обновления Django 1.3, в котором описаны используемые настройки:

# idiom to get path of project
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
# url prefix for user uploaded files, stuff that django has to serve directly
MEDIA_URL = '/media/'
# url prefix for static files like css, js, images
STATIC_URL = '/static/'
# url prefix for *static* /admin media
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
# path to django-served media
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
# path used for collectstatic, *where the webserver not django will expect to find files*
STATIC_ROOT = '/home/user/public_html/static'
# path to directories containing static files for django project, apps, etc, css/js
STATICFILES_DIRS = (
    os.path.join(PROJECT_PATH, 'static'),
)
# List of finder classes that know how to find static files in various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
) 
# Required for all the magic
INSTALLED_APPS = (
    'django.contrib.staticfiles',
)

Подробнее см. В документах: http://docs.djangoproject.com/en/1.3/howto/static-files/.

Я использую nginx и uwsgi для обслуживания приложений django на производстве (я использую runserver для разработки). Я символически связываю мои папки /static и /media (из моего проекта django) в /var/www/vhosts/domain.com/html для поиска nginx. Вы также можете использовать команду collectstatic вместо символьных ссылок. Если он не может найти статический файл, он возвращается к uwsgi (который запускает приложение django).

Вместо uwsgi вы можете использовать fast-cgi или proxy_pass или что угодно. Я предпочитаю uwsgi, потому что он обладает невероятным количеством функций и отличной производительностью. Я запускаю uwsgi как демон с: uwsgi --emperor '/srv/*/*.ini'. Это довольно новая опция, она говорит uwsgi сканировать заданный путь для файлов конфигурации. Когда демон emperor uwsgi находит файл конфигурации, он запускает новый экземпляр uwsgi, используя найденную конфигурацию. Если вы измените свою конфигурацию, демон emperor uwsgi заметит и перезапустит ваше приложение. Вы также можете прикоснуться к файлу конфигурации, чтобы перезагрузить, как с помощью mod_wsgi, и действительно легко настроить новые приложения, когда у вас все настроено изначально.

Соглашения о путях, которым я следую:

/srv/venv/ - virtualenv for project
/srv/venv/app.ini - configuration for uwsgi
/srv/venv/app.sock - uwsgi sock for django
/srv/venv/app.wsgi - wsgi file for uwsgi
/srv/venv/proj - django project
/srv/venv/proj/settings.py - project settings file
/srv/venv/proj/static - static files dir, linked into var/www/vhosts/domain.com/html
/srv/venv/proj/static/admin - admin static files, linked as well
/srv/venv/proj/media - media files dir
/var/www/vhosts/domain.com/html - base directory for nginx to serve static resources from

Это мой nginx.conf:

location / {
    root /var/www/vhosts/domain.com/html;
    index index.html index.html;
    error_page 404 403 = @uwsgi;
    log_not_found  off;
}

location @uwsgi {
    internal;
    include /etc/nginx/uwsgi_params;
    uwsgi_pass unix:/srv/venv/app.sock;
}

Мой файл uwsgi ini (вы также можете использовать xml / yaml / etc):

[uwsgi]
home = /srv/%n
pp = /srv/%n
wsgi-file = /srv/%n/%n.wsgi
socket = /srv/%n/%n.sock
single-intepreter = true
master = true
processes = 2
logto = /srv/%n/%n.log

Вы также должны проверить gunicorn , у него действительно хорошая интеграция с django и хорошая производительность.

2 голосов
/ 06 мая 2011

Я помещаю это здесь на случай, если кто-то захочет получить пример того, как это сделать для Apache и WSGI.Название вопроса сформулировано так, что оно охватывает не только nginx.

Apache / WSGI Daemon

В своем развертывании я решил сохранить информацию о подключении к базе данных из файла settings.py.Вместо этого у меня есть путь /etc/django, который содержит файлы с конфигурацией базы данных.Это подробно описано в ответе на другой вопрос .Однако, как побочный эффект, я могу проверить наличие этих файлов и нахождение проекта по определенному пути, чтобы определить, выполняется ли это как развертывание, и в settings.py я определяю настройки IS_DEV, IS_BETAи IS_PROD как True или False.Найти каталог проекта из settings.py просто:

# Find where we live.
import os
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))

Все, что нуждается в пути к проекту, использует BASE_DIR.Итак, в urls.py у меня есть в конце:

# Only serve static media if in development (runserver) mode.
if settings.IS_DEV:
    urlpatterns += patterns('',
        url(r'^static/(?P<path>.*)$', 'django.views.static.serve', 
            {'document_root': settings.MEDIA_ROOT, 
            'show_indexes': True}),
    )

(у меня также есть другой URL-адрес, который я использую для тестирования пользовательского интерфейса и не хочу в бета-версии или на производстве.)

Это относится к делу сервера разработки.Для производства мне просто нужно настроить конфигурацию Apache для обслуживания статических объектов.(Это приложение для внутренней сети с низкой и средней нагрузкой, поэтому у меня нет легковесного веб-сервера, такого как lighttpd, для обслуживания статических данных, вопреки рекомендации Django docs.) Поскольку я использую Fedora Core, я добавляю *Файл 1026 * в /etc/httpd/conf.d, который выглядит примерно так:

WSGIDaemonProcess djangoproject threads=15
WSGISocketPrefix /var/run/wsgi/wsgi

Alias /django/static/ /var/www/djangoproject/static/
Alias /django/admin/media/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/
WSGIScriptAlias /django /var/www/djangoproject/django.wsgi
WSGIProcessGroup djangoproject

<Directory /var/www/djangoproject>
    Order deny,allow
    Allow from all
</Directory>

<Directory /usr/lib/python2.6/site-packages/django/contrib/admin/media>
    Order deny,allow
    Allow from all
</Directory>

IIRC, ключом здесь является размещение строк Alias перед строкой WSGIScriptAlias.Также убедитесь, что у пользователя нет возможности загрузить ваш код;Я сделал это, поместив статический материал в каталог static, которого нет в моем проекте Django.Вот почему BASE_DIR дает каталог , содержащий каталог проекта Django.

Вы можете опустить строку WSGISocketPrefix.У меня это есть, потому что администратор хочет, чтобы сокеты находились не в месте по умолчанию.

Мой файл WSGI находится в /var/www/djangoproject/django.wsgi (то есть /django.wsgi в репозитории Mercurial) и содержит что-то вроде:

import os
import sys

os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings'
os.environ['DB_CONFIG'] = '/etc/django/db_regular.py'
thisDir = os.path.dirname(__file__)
sys.path.append(thisDir)
sys.path.append(os.path.join(thisDir, 'djangoproject'))
sys.path.append(os.path.join(thisDir, 'lib'))

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Хорошая особенность демонов WSGI заключается в том, что вам просто нужно touch django.wsgi перезапустить ваш демон Django WSGI;вам не нужно перезагружать или перезагружать сервер Apache.Это делает администратора счастливым.

Наконец, так как мой /var/www/djangoproject - это просто репозиторий Mercurial, у меня есть следующее в /var/www/djangoproject/.hg/hgrc:

[hooks]
changegroup.1=find . -name \*.py[co] -exec rm -f {} \;
changegroup.2=hg update
changegroup.3=chgrp -Rf djangoproject . || true
changegroup.4=chmod -Rf g+w,o-rwx . || true
changegroup.5=find . -type d -exec chmod -f g+xs {} \;
changegroup.6=touch django.wsgi # Reloads the app

Это очищает байт-код Python, обновляетрабочая копия, исправляет все настройки и перезапускает демон всякий раз, когда разработчик запускает развертывание, так что любой пользователь из группы djangoproject может войти в него, а не только тот, кто добавил файл.Излишне говорить, что будьте осторожны с тем, кого вы включаете в группу djangoproject.


наборы zeekay STATIC_URL, STATIC_ROOT, STATICFILES_DIRS, STATICFILES_FINDERS и использует "django.contrib.staticfiles" и "django.core.context_processors.static" в его настройках.У меня их нет, поскольку мой код восходит к Django 1.1 и не использует {{ STATIC_ROOT }}.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...