Описание проблемы: Gunicorn не видит static и base.css
При развертывании Django-проекта с использованием Gunicorn в production-среде, распространенной проблемой является некорректное отображение статических файлов, таких как CSS (например, base.css) и JavaScript. Браузер не может загрузить эти ресурсы, что приводит к сломанному интерфейсу и некорректной работе сайта. Часто, все работает нормально в development-режиме (python manage.py runserver), но после перехода на Gunicorn статика перестает отображаться.
Почему это происходит: Краткий обзор работы Gunicorn и Django со статическими файлами
Gunicorn сам по себе не предназначен для обслуживания статических файлов. Он является WSGI-сервером, который служит для запуска Django-приложения. Django, в свою очередь, предоставляет инструменты для работы со статикой, но требует дополнительной настройки для корректной работы в production. В development-режиме, Django автоматически обслуживает статические файлы, но в production это необходимо делегировать другому сервису (например, Nginx или Apache) или использовать специализированные библиотеки (например, WhiteNoise).
Проверка настроек Django для статических файлов
Проверка `settings.py`: `STATIC_URL`, `STATIC_ROOT`, `STATICFILES_DIRS`
Убедитесь, что в вашем файле settings.py правильно настроены параметры, отвечающие за работу со статическими файлами. Вот пример конфигурации:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]STATIC_URL: URL, по которому будут доступны статические файлы (обычно /static/).
STATIC_ROOT: Абсолютный путь к директории, куда Django будет собирать все статические файлы при выполнении команды python manage.py collectstatic. Важно: эта директория не должна находиться внутри директории с кодом вашего проекта. Обычно ее располагают на одном уровне с manage.py.
STATICFILES_DIRS: Список директорий, в которых Django будет искать статические файлы. Используется для хранения статики, специфичной для отдельных приложений или компонентов проекта.
Убедитесь, что `django.contrib.staticfiles` присутствует в `INSTALLED_APPS`
Убедитесь, что приложение django.contrib.staticfiles добавлено в список INSTALLED_APPS в вашем settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# ... ваши приложения ...
]Запуск `python manage.py collectstatic`: Сбор статики в `STATIC_ROOT`
После настройки settings.py необходимо собрать все статические файлы в директорию, указанную в STATIC_ROOT. Для этого выполните команду:
python manage.py collectstaticЭта команда скопирует все статические файлы из ваших приложений (и директорий, указанных в STATICFILES_DIRS) в STATIC_ROOT. Убедитесь, что после выполнения команды в директории STATIC_ROOT находятся ваши статические файлы (например, base.css).
Настройка Gunicorn для обслуживания статических файлов
Как уже упоминалось, Gunicorn не предназначен для непосредственного обслуживания статических файлов. Поэтому необходимо использовать один из следующих подходов:
Вариант 1: Использование WhiteNoise (рекомендовано для простых случаев)
WhiteNoise – это библиотека, которая позволяет Django обслуживать статические файлы напрямую, без использования Nginx или Apache. Это самый простой способ настроить статику в production, особенно если у вас небольшая нагрузка.
Установите WhiteNoise:
pip install whitenoiseДобавьте whitenoise.middleware.WhiteNoiseMiddleware в MIDDLEWARE в settings.py, сразу после SecurityMiddleware:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# ... остальные middleware ...
]Укажите STATIC_ROOT для WhiteNoise:
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')После этого, WhiteNoise будет автоматически обслуживать статические файлы из директории STATIC_ROOT.
Вариант 2: Настройка Nginx или Apache для обслуживания статики (для production)
Для production-окружений с высокой нагрузкой рекомендуется использовать Nginx или Apache для обслуживания статических файлов. Это более сложный, но и более производительный подход. Суть заключается в том, что Nginx (или Apache) напрямую отдает статические файлы, не перенаправляя запросы к Gunicorn. Gunicorn, в свою очередь, обрабатывает только динамические запросы.
Неправильная практика: Не обслуживайте статику напрямую через Gunicorn
Обслуживание статики непосредственно через Django/Gunicorn (без WhiteNoise или Nginx/Apache) крайне не рекомендуется для production. Это приводит к существенному снижению производительности и увеличению нагрузки на сервер, так как Gunicorn не оптимизирован для этой задачи.
Конфигурация Nginx (пример)
Настройка блока server в Nginx для обслуживания статики из `STATIC_ROOT`
В конфигурационном файле Nginx (обычно расположенном в /etc/nginx/sites-available/default или /etc/nginx/conf.d/your_site.conf) необходимо добавить блок, который будет обслуживать статические файлы из STATIC_ROOT.
Пример конфигурации Nginx для Django + Gunicorn + Static
server {
listen 80;
server_name your_domain.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /path/to/your/project/staticfiles; # Укажите ваш STATIC_ROOT
}
location / {
proxy_pass http://127.0.0.1:8000; # Адрес, на котором слушает Gunicorn
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Замените your_domain.com на ваш домен.
Замените /path/to/your/project/staticfiles на абсолютный путь к вашей директории STATIC_ROOT.
Убедитесь, что Gunicorn слушает на указанном адресе (в примере – 127.0.0.1:8000).
Перезапуск Nginx для применения изменений
После внесения изменений в конфигурационный файл Nginx необходимо перезапустить сервис для применения изменений:
sudo systemctl restart nginxРешение проблем и отладка
Проверка прав доступа к файлам в `STATIC_ROOT`
Убедитесь, что у пользователя, от имени которого запускается Gunicorn, есть права на чтение файлов в директории STATIC_ROOT.
Очистка кэша браузера: Часто забываемый шаг
После внесения изменений в статические файлы (например, base.css) необходимо очистить кэш браузера, чтобы браузер загрузил новые версии файлов. Самый простой способ – использовать сочетание клавиш Ctrl + Shift + R (или Cmd + Shift + R на Mac).
Просмотр логов Gunicorn и Nginx на наличие ошибок
Просматривайте логи Gunicorn и Nginx на наличие ошибок. Ошибки в логах могут указать на проблемы с конфигурацией или правами доступа.
Логи Gunicorn обычно расположены в файле, указанном при запуске Gunicorn (например, --log-file /var/log/gunicorn/error.log).
Логи Nginx обычно расположены в /var/log/nginx/error.log и /var/log/nginx/access.log.
Использование инструментов разработчика браузера для проверки загрузки ресурсов (base.css и т.д.)
Используйте инструменты разработчика браузера (обычно открываются клавишей F12) для проверки загрузки статических ресурсов. Во вкладке "Network" вы можете увидеть, какие файлы были загружены, какие ошибки произошли и сколько времени заняла загрузка каждого файла. Обратите внимание на статус код (200 – OK, 404 – Not Found, 500 – Internal Server Error) и тип контента (например, text/css для CSS-файлов).