2016-07-12 8 views
3

Ich führe ein Django-Projekt, das alle statischen und Mediendateien zu Amazon S3 hinzufügt. Ich verwende eine settings.py-Konfiguration, die ich in der Vergangenheit oft verwendet habe und die für mehrere andere Projekte funktioniert (siehe unten).Django Collectstatic Ergebnis in S3ResponseError: 301 dauerhaft verschoben

Wenn ich die selbe settings.py Datei auf meinem eigenen localhost verwende. Ich kann python manage.py collectstatic --noinput fein ausführen und es wird alle statischen Dateien auf Amazon S3 hochladen. Aber wenn ich mein Projekt auf einen Elastic Beanstalk Application Server setze und denselben Befehl mit den gleichen Einstellungen ausführe, bekomme ich S3ResponseError: 301 Moved Permanently.

Meine Einstellungen sind:

AWS_STORAGE_BUCKET_NAME = 's3.cupcard.com' 
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME 
AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat' 
AWS_S3_SECURE_URLS = False 
AWS_S3_URL_PROTOCOL = 'http:' # Replace with 'https:' if you're not using http. 

STATICFILES_LOCATION = 'static' 
STATIC_URL = "http://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION) 
STATICFILES_STORAGE = 'lindshop.utils.custom_storages.CachedS3BotoStorage' 

MEDIAFILES_LOCATION = 'media' 
MEDIA_URL = "http://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION) 
DEFAULT_FILE_STORAGE = 'lindshop.utils.custom_storages.MediaStorage' 

Die lindshop.utils.custom_storages.CachedS3BotoStorage sieht wie folgt aus:

class EuropeConnection(S3Connection): 
    DefaultHost = "s3-eu-west-1.amazonaws.com" 

class CachedS3BotoStorage(S3BotoStorage): 
    connection_class = EuropeConnection 
    location = settings.STATICFILES_LOCATION 

    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): 
     non_gzipped_file_content = content.file 
     name = super(CachedS3BotoStorage, self).save(name, content) 
     content.file = non_gzipped_file_content 
     self.local_storage._save(name, content) 
     return name 

Um zusammenzufassen und mich zu wiederholen.

  1. Ich kann von localhost ausführen. Ich habe auch bestätigt, dass ich auf die Dateien in der S3-Instanz zugreifen kann, die der localhost dort mit dem Befehl collectstatic eingerichtet hat. Wenn ich dasselbe mit einer Elastic Beanstalk-Anwendung mit den gleichen Einstellungen mache, erhalte ich einen Fehler.
  2. Ich habe die gleichen Einstellungen in anderen Projekten zuvor ohne Probleme verwendet. Das einzige, was geändert wurde, ist der Bucket-Name.
  3. Der Fehler, den ich bekomme, wenn ich collectstatic auf dem EB-Server ausführen, ist S3ResponseError: 301 Moved Permanently.

Volltraceback:

caused by: Traceback (most recent call last): 
    File "/opt/python/run/venv/bin/django-admin.py", line 5, in <module> 
    management.execute_from_command_line() 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line 
    utility.execute() 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 345, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 399, in execute 
    output = self.handle(*args, **options) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 176, in handle 
    collected = self.collect() 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 107, in collect 
    handler(path, prefixed_path, storage) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 325, in copy_file 
    if not self.delete_file(path, prefixed_path, source_storage): 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 238, in delete_file 
    if self.storage.exists(prefixed_path): 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/storages/backends/s3boto.py", line 446, in exists 
    return k.exists() 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/boto/s3/key.py", line 539, in exists 
    return bool(self.bucket.lookup(self.name, headers=headers)) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 143, in lookup 
    return self.get_key(key_name, headers=headers) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 193, in get_key 
    key, resp = self._get_key_internal(key_name, headers, query_args_l) 
    File "/opt/python/run/venv/local/lib/python2.7/site-packages/boto/s3/bucket.py", line 231, in _get_key_internal 
    response.status, response.reason, '') 
    boto.exception.S3ResponseError: S3ResponseError: 301 Moved Permanently 

    (ElasticBeanstalk::ExternalInvocationError) 
+0

Bitte aktualisieren Sie Ihre Frage und buchen Sie die komplette Traceback. –

+0

Ist dieser Eimer außerhalb der US-Region? –

+0

Ja, es ist in eu-west-1 erstellt. Deshalb verwendet es eine Verbindungsklasse mit 'DefaultHost =" s3-eu-west-1.amazonaws.com "' –

Antwort

4

Ich fand heraus, dass das Problem ist, dass ein Update auf das Django-Modul django-storages, die ich verwendet.

host = setting('AWS_S3_HOST', S3Connection.DefaultHost) 

Was passiert, ist, dass der Host automatisch auf s3.amazonaws.com gesetzt ist und weil es bereits einen Host-Satz, wenn es schafft die Verbindung: In dem Update haben sie einen Standardwert S3BotoStorage.host, indem sie es in der folgenden Art und Weise der Zuordnung hinzugefügt mit boto (AWS offizielle Python-Paket), verwendet es nie die DefaultHost = "s3-eu-west-1.amazonaws.com", die ich in meiner EuropeConnection-Klasse hinzugefügt.

Der Weg, um dieses Problem zu lösen, ist Django-Speicher-Einstellungen Wert AWS_S3_HOST (Neu) in Ihrem settings.py.

AWS_S3_HOST = "s3-eu-west-1.amazonaws.com" 
Verwandte Themen