Обслуживание статических/медийных файлов Django через IBM Cloud Foundry
Приветствую всех!
Нужна помощь в определении правильной концепции развертывания простого приложения Django, связанного с обслуживанием статических/медиа файлов. Цель - использовать возможности IBM Cloud Foundry, поэтому вопрос, вероятно, больше зависит от платформы.
Проблема в том, что Django в режиме DEBUG=False больше не заботится о статических файлах, так что пришло время для некоторых фантастических конфигураций веб-сервера. Как и в случае с IBM Cloud Foundry, я не могу найти правильный способ обслуживать мои медиа ссылки, поэтому изображения не видны. Например, при моей конфигурации я получаю '/media/...'
вместо '/static/media/...'
. Решение должно быть относительно очевидным, но я не могу его найти.
Для IBM Cloud Foundry мой manifest.yml
:
applications:
- name: onlinecourse
routes:
- route: $HOST.$DOMAIN
memory: 128M
buildpack: python_buildpack
- name: onlinecourse-nginx
routes:
- route: $HOST.$DOMAIN/static
memory: 64M
buildpack: staticfile_buildpack
Так что на самом деле есть два приложения: 'onlinecourse' управляет файлами Django, а 'onlinecourse-nginx' обслуживает статику. Это своего рода boilerplates, который использует использование предварительно настроенного staticfile_buildpack
с nginx start up где-то внутри, так что, вероятно, это и есть "дьявол".
Первым делом, моя модель:
class Course(models.Model):
...
image = models.ImageField(upload_to='course_images/')
...
В шаблоне я пытаюсь вывести изображение следующим образом:
<img src="{{ course.image.url }}" width="240px" height="240px" ...
(рассматривайте здесь 'course' как экземпляр Course). Это дает мне ссылку как '/media/course_images/...'
, так что это работает как шарм в DEBUG=True.
Мой settings.py довольно общий. Ключевыми значениями являются:
INSTALLED_APPS = [
....
'django.contrib.staticfiles',
]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(STATIC_ROOT, 'media')
MEDIA_URL = '/media/'
Также в urls.py есть:
urlpatterns = [
....
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Когда я развертываю с DEBUG=False и своим manifest.yml
на IBM Cloud Foundry, я получаю полностью функциональное приложение. Также я терпеливо запускаю 'python3 manage.py collectstatic'
перед этим (но не уверен, что это действительно необходимо, потому что я вижу в логах сборки, что он запускается автоматически на этапе сборки). Все в порядке с js и css, кроме ссылок для изображений ('/media/course_images/...'
). Кстати, фактическая ссылка на nginx через '/static/media/course_images/...'
жива и готова к работе.
Как их поженить?
1-й подход, я попробовал явно поиграть с конструкцией Django {% static ... %}
и конфигом STATICFILES_DIRS
, это частично решает проблему. Но ссылки становятся нерабочими при DEBUG=True ((.
2-й подход, кажется очевидным, чтобы внести некоторые изменения в onlinecourse-nginx
приложение. Но поскольку это не чистый nginx, я не вижу никакого подходящего способа немного встряхнуть его. Документация staticfile-buildpack
недостаточно щедра, чтобы обеспечить прямой способ подачи некоторых пользовательских конфигураций... Так что, вероятно, мне придется отказаться от этого и использовать что-то другое. Буду очень признателен, если вы поделитесь любым советом.
3-й подход, есть безумный способ позволить Django обслуживать статику даже в режиме DEBUG=False самостоятельно с помощью некоторых уродливых трюков типа 'runserver --insecure'
или чего-то еще. Я нахожу это креативным, но, вероятно, его следует избегать любой ценой.
Я что-то упускаю? Какова наилучшая практика в этом случае?
Хотелось бы верить, что есть некоторые Django jedy`s, которые сталкивались с подобными проблемами и решили их. Также в IBM Cloud Foundry (к сожалению, скоро устаревающем) тоже должны быть опытные ниндзя, которые подскажут, как это сделать.
С наилучшими пожеланиями!