How to setup django-compressor on heroku, offline compression to S3

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

I followed every QA suggestions found on SO and in different blogs, Everything works ok on my dev machine and nothing works on heroku.

here are my settings:

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 

When i run collectstatic/compress everything is ok, i see the files being collected to S3 and put in proper places. I see the manifest file.

Loading any page with compressor tag, show an error OfflineGenerationError: You have offline compression enabled but key "d2a53169c44dec41ce3ee7da19b2b9d4" is missing from offline manifest. Running python manage.py compress again solves nothing. when i check the manifest file, indeed the key it looks for doesn't exist.

What is going wrong here?

Question i already checked:

How to configure django-compressor and django-staticfiles with Amazon's S3?

Django Compressor with S3 URL Heroku

Configuring django-compressor with remote storage (django-storage - amazon s3)

回答1:

On my side I have very similar config, and I'm successfully using compressor for more than 2 years.

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 

I'm running python managep.py compress locally, and having manifest generated on my static files directory. Heroku only deals with the collecstatic and delivers the most recent manifest version to my cdn.

Regards,



回答2:

I completed the above solution with some lines, to fix the problem that create many (multiples) manifest_%.json in Amazon S3

in setting.py:

STATICFILES_STORAGE = 'your_package.s3utils.CachedS3BotoStorage' 

in 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:

I found a git repository that contains post_compile hooks to solve this problem. It runs compress after Heroku built the Django app (and also installs lessc if you need less in your compressor settings).

https://github.com/nigma/heroku-django-cookbook



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!