Обслуживание статических/медийных файлов 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 (к сожалению, скоро устаревающем) тоже должны быть опытные ниндзя, которые подскажут, как это сделать.

С наилучшими пожеланиями!

Вернуться на верх