heroku & django: el server no carga files estáticos

Anoche decidí poner en producción mi proyecto de escuela django. Para esto usé Heroku. Todo va bien, pero "el último toque" me está volviendo loco. Parece que no ve mis files estáticos como bootstrap css'es en el website y no sé por qué porque, por ejemplo, ball.jpg está cargado y el css de administración también está cargado. Si alguien pudiera encontrar el problema con el que estoy lidiando durante las últimas 10 horas, sería un salvavidas 🙂

Puedes ver los resultados aquí

Mi settings.py

from django.conf import settings if not settings.DEBUG: import os import dj_database_url BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '*****' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False ALLOWED_HOSTS = ["*"] # Honor the 'X-Forwarded-Proto' header for request.is_secure() SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # Application definition INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'crispy_forms', 'team', 'tournament', 'geoposition', 'emailing', ) MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', ) ROOT_URLCONF = 'football.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'football.wsgi.application' # Database # https://docs.djangoproject.com/en/1.8/ref/settings/#databases DATABASES = settings.DATABASES DATABASES['default'] = dj_database_url.config() # Internationalization # https://docs.djangoproject.com/en/1.8/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static asset configuration STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, "media", "static_root") STATICFILES_DIRS = ( os.path.join(BASE_DIR, "media_in_pro", "static"), ) # Simplified static file serving. # https://warehouse.python.org/project/whitenoise/ STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage' # MEDIA SETTINGS MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, "media", "media_root") # CRISPY FORM SETTINGS CRISPY_TEMPLATE_PACK = 'bootstrap3' # Django-Geoposition GEOPOSITION_MAP_OPTIONS = { 'minZoom': 8, 'maxZoom': 15, 'center': {'lat': 53.13248859999999, 'lng': 23.168840300000056 }, } GEOPOSITION_MAP_WIDGET_HEIGHT = 240 GEOPOSITION_MARKER_OPTIONS = { 'cursor': 'move' } 

Mientras Git empuja

 remote: Compressing source files... done. remote: Building source: remote: remote: -----> Using set buildpack heroku/python remote: -----> Python app detected remote: -----> Installing dependencies with pip remote: remote: -----> Preparing static assets remote: Running collectstatic... remote: Post-processed 'admin/js/admin/DateTimeShortcuts.js' as 'admin/js/admin/DateTimeShortcuts.140919a6a17e.js' (...) remote: 82 static files copied to '/app/media/static_root', 82 post-processed. remote: remote: remote: -----> Discovering process types remote: Procfile declares types -> web remote: remote: -----> Compressing... done, 48.6MB remote: -----> Launching... done, v51 remote: https://footballapp.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy.... done. 

Mis loggings heroku –tail:

 2015-11-15T20:37:12.426289+00:00 heroku[slug-compiler]: Slug comstacktion started 2015-11-15T20:37:12.426301+00:00 heroku[slug-compiler]: Slug comstacktion finished 2015-11-15T20:37:12.456467+00:00 heroku[web.1]: State changed from up to starting 2015-11-15T20:37:16.171136+00:00 heroku[web.1]: Starting process with command `gunicorn football.wsgi` 2015-11-15T20:37:16.794898+00:00 heroku[web.1]: Stopping all processes with SIGTERM 2015-11-15T20:37:17.969513+00:00 app[web.1]: [2015-11-15 20:37:17 +0000] [3] [INFO] Shutting down: Master 2015-11-15T20:37:17.956039+00:00 app[web.1]: [2015-11-15 20:37:17 +0000] [9] [INFO] Worker exiting (pid: 9) 2015-11-15T20:37:17.956047+00:00 app[web.1]: [2015-11-15 20:37:17 +0000] [10] [INFO] Worker exiting (pid: 10) 2015-11-15T20:37:17.956935+00:00 app[web.1]: [2015-11-15 20:37:17 +0000] [3] [INFO] Handling signal: term 2015-11-15T20:37:18.765840+00:00 heroku[web.1]: Process exited with status 0 2015-11-15T20:37:18.579708+00:00 app[web.1]: [2015-11-15 20:37:18 +0000] [3] [INFO] Listening at: http://0.0.0.0:46020 (3) 2015-11-15T20:37:18.579713+00:00 app[web.1]: [2015-11-15 20:37:18 +0000] [3] [INFO] Using worker: sync 2015-11-15T20:37:18.588372+00:00 app[web.1]: [2015-11-15 20:37:18 +0000] [9] [INFO] Booting worker with pid: 9 2015-11-15T20:37:18.578828+00:00 app[web.1]: [2015-11-15 20:37:18 +0000] [3] [INFO] Starting gunicorn 19.3.0 2015-11-15T20:37:18.655018+00:00 app[web.1]: [2015-11-15 20:37:18 +0000] [10] [INFO] Booting worker with pid: 10 2015-11-15T20:37:19.993385+00:00 heroku[web.1]: State changed from starting to up 2015-11-15T20:37:26.757037+00:00 heroku[router]: at=info method=GET path="/" host=footballapp.herokuapp.com request_id=16bde5f5-98bd-48a0-bde4-269947950c15 fwd="178.42.56.94" dyno=web.1 connect=1ms service=114ms status=200 bytes=4597 2015-11-15T20:37:27.090478+00:00 heroku[router]: at=info method=GET path="/static_root/img/cartoon-soccer-6.3dda712041b4.jpg" host=footballapp.herokuapp.com request_id=726fdf17-a3bb-4edc-94ee-8e0291c4fb68 fwd="178.42.56.94" dyno=web.1 connect=0ms service=4ms status=200 bytes=24769 2015-11-15T20:37:27.314794+00:00 heroku[router]: at=info method=GET path="/static_root/bootstrap-3.3.5-dist/js/npm.ccb7f3909e30.js" host=footballapp.herokuapp.com request_id=d22d2938-6955-4c0a-9c30-71a2dc408106 fwd="178.42.56.94" dyno=web.1 connect=1ms service=5ms status=200 bytes=566 2015-11-15T20:37:27.299303+00:00 heroku[router]: at=info method=GET path="/static_root/bootstrap-3.3.5-dist/js/bootstrap.8015042d0b4a.js" host=footballapp.herokuapp.com request_id=afceaef7-b06c-4523-b855-f6966a2829fa fwd="178.42.56.94" dyno=web.1 connect=0ms service=3ms status=200 bytes=14380 2015-11-15T20:37:43.569729+00:00 heroku[router]: at=info method=GET path="/" host=footballapp.herokuapp.com request_id=ab185988-12f4-4b78-a7d7-53eae067e891 fwd="178.42.56.94" dyno=web.1 connect=0ms service=8ms status=200 bytes=4597 2015-11-15T20:37:43.769540+00:00 heroku[router]: at=info method=GET path="/static_root/img/cartoon-soccer-6.3dda712041b4.jpg" host=footballapp.herokuapp.com request_id=e01d8276-1220-45f8-b9b1-866cd5ab2e7d fwd="178.42.56.94" dyno=web.1 connect=0ms service=2ms status=200 bytes=24769 2015-11-15T20:37:44.086677+00:00 heroku[router]: at=info method=GET path="/static_root/bootstrap-3.3.5-dist/js/npm.ccb7f3909e30.js" host=footballapp.herokuapp.com request_id=3172e050-63d5-421d-b3b2-cca661739c34 fwd="178.42.56.94" dyno=web.1 connect=0ms service=1ms status=200 bytes=566 2015-11-15T20:37:44.064945+00:00 heroku[router]: at=info method=GET path="/static_root/bootstrap-3.3.5-dist/js/bootstrap.8015042d0b4a.js" host=footballapp.herokuapp.com request_id=06b09fae-36db-4ac2-9d8d-fe0a2b3cfb06 fwd="178.42.56.94" dyno=web.1 connect=0ms service=1ms status=200 bytes=14380 2015-11-15T20:38:54.229389+00:00 heroku[api]: Deploy b75838d by tofik1432@gmail.com 2015-11-15T20:38:54.229389+00:00 heroku[api]: Release v51 created by tofik1432@gmail.com 2015-11-15T20:38:54.375061+00:00 heroku[slug-compiler]: Slug comstacktion started 2015-11-15T20:38:54.375070+00:00 heroku[slug-compiler]: Slug comstacktion finished 2015-11-15T20:38:54.509049+00:00 heroku[web.1]: State changed from up to starting 2015-11-15T20:38:57.508059+00:00 heroku[web.1]: Starting process with command `gunicorn football.wsgi` 2015-11-15T20:38:59.282919+00:00 app[web.1]: [2015-11-15 20:38:59 +0000] [3] [INFO] Starting gunicorn 19.3.0 2015-11-15T20:38:59.349517+00:00 app[web.1]: [2015-11-15 20:38:59 +0000] [10] [INFO] Booting worker with pid: 10 2015-11-15T20:38:59.283351+00:00 app[web.1]: [2015-11-15 20:38:59 +0000] [3] [INFO] Listening at: http://0.0.0.0:57838 (3) 2015-11-15T20:38:59.283475+00:00 app[web.1]: [2015-11-15 20:38:59 +0000] [3] [INFO] Using worker: sync 2015-11-15T20:38:59.286946+00:00 app[web.1]: [2015-11-15 20:38:59 +0000] [9] [INFO] Booting worker with pid: 9 2015-11-15T20:38:59.734335+00:00 heroku[web.1]: State changed from starting to up 2015-11-15T20:39:00.743234+00:00 heroku[web.1]: Stopping all processes with SIGTERM 2015-11-15T20:39:02.232759+00:00 app[web.1]: [2015-11-15 20:39:02 +0000] [9] [INFO] Worker exiting (pid: 9) 2015-11-15T20:39:02.232763+00:00 app[web.1]: [2015-11-15 20:39:02 +0000] [10] [INFO] Worker exiting (pid: 10) 2015-11-15T20:39:02.252311+00:00 app[web.1]: [2015-11-15 20:39:02 +0000] [3] [INFO] Handling signal: term 2015-11-15T20:39:02.297059+00:00 app[web.1]: [2015-11-15 20:39:02 +0000] [3] [INFO] Shutting down: Master 

EDITAR: descubrí que parece que no se cargan mis html de inclusión en base.html, ¿alguien tuvo este problema?

Tuve un problema similar en Heroku recientemente. Parece que Django no puede servir activos estáticos por sí solo en la producción. Pude usar WhiteNoise para servir la estática en su lugar. Primero instálalo:

$ pip install whitenoise

Asegúrese de agregar whitenoise a su requirements.txt también.

Ahora agregue lo siguiente a su wsgi.py :

 from django.core.wsgi import get_wsgi_application from whitenoise.django import DjangoWhiteNoise application = get_wsgi_application() application = DjangoWhiteNoise(application) 

Finalmente, configure whitenoise en su settings.py:

 STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' 

o dependiendo de las versiones de Django y WhiteNoise que esté ejecutando:

 STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage' 

Además, asegúrese de tener sus statistics estáticas configuradas correctamente en su settings.py

 PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') STATIC_URL = '/static/' # Extra places for collectstatic to find static files. STATICFILES_DIRS = ( os.path.join(PROJECT_ROOT, 'static'), ) 

Más información: https://devcenter.heroku.com/articles/django-assets