2013-01-19 19 views
10

Sto usando django-storages per file statici con S3 (e S3BotoStorage). Quando eseguo collecttatic dalla mia macchina locale, il comportamento è come previsto, in cui solo i file modificati vengono trasferiti a S3. Questo processo ha bisogno di python-dateutils 1.5 per controllare la modifica del tempo.Django collectstatic di Heroku spinge a S3 ogni volta

Tuttavia, fare lo stesso su Heroku risulta in ogni file che viene spinto a prescindere, sebbene la configurazione sia la stessa. Ho quindi esaminato il tempo modificato dei file su Heroku stesso, e sembra che os.stat (static_filename) .st_mtime sia lo stesso dell'ora dell'ultima pressione.

È questo comportamento previsto? Heroku copia i file anche quando non ci sono cambiamenti da git?

risposta

5

Ho appena avuto lo stesso identico problema e ho contattato il supporto di Heroku per scoprire cosa sta succedendo. La mia domanda a loro era

Ho incontrato un problema funky che fa alcune distribuzioni. Sembra che su ogni push la data modificata su tutti i file sia aggiornata al momento in cui si verifica una nuova distribuzione/git push. È questo comportamento previsto?

Quando si considera che il comando di Django collectstatic controlla solo la data di modifica dei file al momento di valutare se il file deve essere copiato in tutto al backend stoccaggio finale per le attività statiche, significa che su ogni nuova spinta, tutti i file vengono prima rimossi dal archiviazione remota (in questo caso S3) e quindi ricaricata. Questo è un processo molto lento e dispendioso in termini di larghezza di banda consumata e richieste fatte.

La risposta che ho ricevuto oggi da "Caio", uno dei personale di supporto di Heroku, era

Salve, questo è come funziona attualmente, sì. Sto inoltrando il tuo feedback al nostro team di runtime per vedere se possiamo impacchettare i file con le loro date originali.

+1

Un altro approccio potrebbe essere quello di avere gli hash del back-end di archiviazione invece dell'ultima modifica. S3 ha un etag che è l'md5 del file, ma non penso che sia documentato. –

0

Sono d'accordo che questo è fastidioso- ci sono un paio di cose che puoi fare. Sovrascrivo il comando collectstatic e lo collego nelle impostazioni di produzione. Di seguito è riportato il comando che uso:

`` `

from django.core.management.base import BaseCommand 
class Command(BaseCommand): 
    args = '<none>' 
    help = "disables collectstatic cmd in contrib" 
    def handle(self, *args, **kwargs): 
     print 'collectstatic disabled' 

` ``

ho tenere questo in mysite/disablecollectstatic/gestione/comandi Poi nelle impostazioni di produzione:

INSTALLED_APPS += ('mysite.disablecollectstatic',) 

In alternativa è possibile utilizzare il fatto che Heroku esegue un ciclo di prova prima di eseguire effettivamente il comando. Se fallisce, non verrà eseguito, il che significa che si potrebbe escogitare un errore (da forse cancellando la radice statica nelle impostazioni, per esempio), ma questo approccio mi rende nervoso:

https://devcenter.heroku.com/articles/django-assets#detection

+1

È possibile disabilitare completamente il comando collectstatic impostando un ambiente var, se è quello che si sta cercando: https://devcenter.heroku.com/articles/django-assets#disabling-collectstatic –

1

Come confermato da Alen, Heroku cambia la data di modifica dei file quando viene distribuito. Tuttavia, Amazon S3 ha anche un attributo chiamato etag che è un hash md5 del contenuto del file. È possibile utilizzarlo per verificare se i file sono stati modificati anziché la data di modifica, come implementato in this Django snippet.

Ho preso quel codice, l'ho impacchettato e corretto alcuni errori che ho trovato e lo ho inserito su Github come django-s3-collectstatic. Include un nuovo comando di gestione fasts3collectstatic che carica solo nuovi file. Controlla la pagina di Github per le istruzioni di installazione.

1

Perché non eseguire collectstatic dal computer locale?

python manage.py collectstatic --noinput --settings=settings.[prod] 
6

consiglio vivamente di utilizzare il collectfast package per qualsiasi distribuzione statica Django a S3, sia esso locale o dal server Heroku. Ignora le date modificate e utilizza gli hash md5, che l'API s3 fornisce molto rapidamente e la cache (facoltativa) per rendere lo zoom delle distribuzioni statiche. Sono state necessarie le distribuzioni statiche da ~ 10-15 minuti a < per 2 minuti e vengono distribuiti solo i file effettivamente modificati.

+0

Grazie! Ci proveremo. –

15

Prova a impostare DISABLE_COLLECTSTATIC=1 come impostazione dell'ambiente per la tua app, che dovrebbe disabilitarla dall'esecuzione su ogni push.

veda questo articolo per i dettagli - https://devcenter.heroku.com/articles/django-assets:

> Sometimes, you may not want Heroku to run collectstatic on your behalf. 
> You can disable collectstatic by enabling user-env-compile as well: 

$ heroku labs:enable user-env-compile 
$ heroku config:set DISABLE_COLLECTSTATIC=1 

Ho scoperto che semplicemente impostando la configurazione farà - non c'è bisogno di abilitare anche user-env-compile - può essere che che questo è passato dai laboratori in produzione ?

NB la distribuzione è gestita dal pitone buildpack Heroku, che potete vedere qui - https://github.com/heroku/heroku-buildpack-python/

EDIT 1

Ho appena fatto un po 'di test su questo, e posso confermare che DISABLE_COLLECTSTATIC effettivamente disabilita collectstatic, indipendentemente dall'impostazione di user-env-compile - Penso che sia ora nel trunk principale (ma questa è la speculazione). Non sembra preoccuparsi di quale sia l'impostazione - se DISABLE_COLLECTSTATIC esiste come una configurazione, viene utilizzato.

+0

tu mi hai salvato la giornata. – levi

Problemi correlati