Как настроить django-compressor на heroku, автономное сжатие до S3
Я следил за каждыми предложениями QA, найденными на SO и в разных блогах. Все работает нормально на моей машине dev, и ничего не работает на герою.
вот мои настройки:
DEFAULT_FILE_STORAGE = 'arena.utils.MediaRootS3BotoStorage' # media files
# storage
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_PRELOAD_METADATA = True # necessary to fix manage.py collectstatic command to only upload changed files instead of all files
S3_URL = 'https://%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
MEDIA_URL = S3_URL + '/media/'
STATIC_URL = S3_URL + '/static/'
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
COMPRESS_URL = STATIC_URL
COMPRESS_OFFLINE = True
COMPRESS_STORAGE = 'utils.CachedS3BotoStorage'
STATICFILES_STORAGE = COMPRESS_STORAGE
Когда я запускаю collectstatic/compress, все в порядке, я вижу, что файлы собираются на S3 и помещаются в соответствующие места. Я вижу файл манифеста.
Загрузка любой страницы с тегом компрессора, сообщение об ошибке OfflineGenerationError: You have offline compression enabled but key "d2a53169c44dec41ce3ee7da19b2b9d4" is missing from offline manifest.
Запуск python manage.py compress
снова ничего не решает. когда я проверяю файл манифеста, действительно, ключ, который он ищет, не существует.
Что здесь происходит?
Вопрос я уже проверен:
Как настроить django-compress и django-staticfiles с помощью S3 Amazon?
Django Compressor с URL-адресом S3 Heroku
Настройка django-компрессора с удаленным хранилищем (django-storage - amazon s3)
Ответы
Ответ 1
На моей стороне у меня очень похожая конфигурация, и я успешно использую компрессор более 2 лет.
settings.py
COMPRESS_STORAGE = 'MyAwesomeApp.app.CachedS3BotoStorage.CachedS3BotoStorage'
AWS_ACCESS_KEY_ID = '#######'
AWS_SECRET_ACCESS_KEY = '########################+#########+BqoQ'
AWS_STORAGE_BUCKET_NAME = 'myAmazonS3cdn.myawesomewebsite.com'
AWS_S3_SECURE_URLS = False
AWS_QUERYSTRING_AUTH = False
COMPRESS_ROOT = 'MyAwesomeApp/static'
STATIC_ROOT = 'MyAwesomeApp/static/javascript'
COMPRESS_OUTPUT_DIR = 'compressed'
STATICFILES_STORAGE = COMPRESS_STORAGE
STATIC_URL = "http://myAmazonS3cdn.myawesomewebsite.com/"
COMPRESS_URL = STATIC_URL
COMPRESS_ENABLED = True
CachedS3BotoStorage.py
from django.core.files.storage import get_storage_class
from storages.backends.s3boto import S3BotoStorage
from django.core.files.base import File
class CachedS3BotoStorage(S3BotoStorage):
"""
S3 storage backend that saves the files locally, too.
"""
def __init__(self, *args, **kwargs):
super(CachedS3BotoStorage, self).__init__(*args, **kwargs)
self.local_storage = get_storage_class("compressor.storage.CompressorFileStorage")()
def save(self, name, content):
name = super(CachedS3BotoStorage, self).save(name, content)
self.local_storage._save(name, content)
return name
Я запускаю python managep.py compress локально и имея манифест, сгенерированный в каталоге статических файлов. Heroku использует только коллектив и предоставляет самую последнюю версию манифеста для моего cdn.
Привет,
Ответ 2
Я выполнил вышеупомянутое решение с некоторыми строками, чтобы исправить проблему, которая создает много (кратных) манифестов _%. json в Amazon S3
в settings.py:
STATICFILES_STORAGE = 'your_package.s3utils.CachedS3BotoStorage'
в s3utils.py:
from storages.backends.s3boto import S3BotoStorage
from django.core.files.storage import get_storage_class
class CachedS3BotoStorage(S3BotoStorage):
"""
S3 storage backend that saves the files locally, too.
"""
location = 'static'
def __init__(self, *args, **kwargs):
super(CachedS3BotoStorage, self).__init__(*args, **kwargs)
self.local_storage = get_storage_class(
"compressor.storage.CompressorFileStorage")()
def url(self, name):
"""
Fix problem images admin Django S3 images
"""
url = super(CachedS3BotoStorage, self).url(name)
if name.endswith('/') and not url.endswith('/'):
url += '/'
return url
def save(self, name, content):
name = super(CachedS3BotoStorage, self).save(name, content)
self.local_storage._save(name, content)
return name
# HERE is secret to dont generating multiple manifest.json and to delete manifest.json in Amazon S3
def get_available_name(self, name):
if self.exists(name):
self.delete(name)
return name
Ответ 3
Я нашел репозиторий git, который содержит post_compile hooks для решения этой проблемы. Он запускает сжатие после того, как Heroku построил приложение Django (а также установил lessc
, если вам нужно меньше настроек компрессора).
https://github.com/nigma/heroku-django-cookbook