在Heroku上使用gunicorn服务器的Django项目不提供静态文件

时间:2012-08-16 19:18:51

标签: django heroku gunicorn static-files

我的Django 1.3项目提供开发服务器上的静态文件,但是没有提供gunicorn服务器静态文件。我按照this Heroku guide的步骤进行了操作。

当我在指南中使用proc文件的内容时( web: gunicorn myproject_django.wsgi -b 0.0.0.0:$PORT)我的项目未被Heroku识别。

然后我将Procfile更改为:

web: python myproject_django/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 3

现在我的应用运行除了静态文件(css不活动或图像)。

我的项目树:

.
├── Procfile
├── myproject_django
│   ├── core
│   │   ├── admin.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── static
│   │   │   ├── css
│   │   │   │   ├── base.css
│   │   │   │   ├── layout.css
│   │   │   │   
│   │   │   └── media
│   │   │       ├── pek.ico
│   │   │       ├── pek.png
│   │   │       ├── pek_symbol.png
│   │   ├── tests.py
│   │   └── views.py
│   ├── __init__.py
│   ├── manage.py
│   ├── settings.py
│   ├── templates
│   │   └── core
│   │       ├── home.html
│   │       └── install.html
│   └── urls.py
└── requirements.txt

settings.py的潜在相关部分

MEDIA_ROOT = ''

MEDIA_URL = '/static/media'

STATIC_ROOT = ''

STATIC_URL = '/static/'

ADMIN_MEDIA_PREFIX = '/static/admin/'

STATICFILES_DIRS = (
    os.path.abspath(__file__)+'/..'+'/myproject_django/core/static', 
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core',
    'gunicorn',
    'django.contrib.admin',
)

修改

在Francis Yaconiello的参赛作品后,我调整了以下内容:

在settings.py

STATIC_ROOT = os.path.join(os.getcwd(),'core/static')
STATICFILES_DIRS = ( os.path.abspath(__file__)+'/..'+'/core/static', )

在gitignore:

staticfiles/*

然后提交。 最后跑了heroku run python myproject_django/manage.py collectstatic

但是当我查看网页时,仍然没有提供静态文件。 鉴于我的目录树,为什么这些更改不起作用?

EDIT2

我仍然没有看到我的静态文件。当我在DEBUG=True时点击图片时,我得到了这个:

Request URL: http://myproject.herokuapp.com/static/media/pek.png

(请注意,staticfiles目录为空)

.
├── Procfile
├── myproject_django
│   ├── admin
│   ├── core
│   │   ├── admin.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── static
│   │   │   ├── css
│   │   │   │   ├── base.css
│   │   │   │   ├── layout.css
│   │   │   └── media
|   |   |       ├── pek.ico
|   │   │       ├── pek.png
|   │   │       ├── pek_symbol.png
│   │   ├── tests.py
│   │   ├── views.py
│   ├── __init__.py
│   ├── manage.py
│   ├── settings.py
│   ├── staticfiles
│   ├── templates
│   │   └── core
│   │       ├── 404.html
│   │       ├── 500.html
│   │       ├── home.html
│   │       └── install.html
│   ├── urls.py
└── requirements.txt

在settings.py

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'static/media')
STATIC_ROOT = os.path.join(PROJECT_PATH,'staticfiles')
STATICFILES_DIRS = (
    os.path.join(PROJECT_PATH, 'core/static'),
)

5 个答案:

答案 0 :(得分:5)

指定您的STATIC_ROOT

我通常把它设置为:

import os
STATIC_ROOT = os.path.join(os.getcwd(), "staticfiles")

在项目中创建该目录

mkdir staticfiles

确保静态文件的内容不是git跟踪的

nano .gitignore

添加

staticfiles/*

然后提交它并推送到heroku。

最后,

heroku run python manage.py collectstatic

修改

STATIC_ROOT = os.path.join(os.getcwd(),'core/static')
STATICFILES_DIRS = ( os.path.abspath(__file__)+'/..'+'/core/static', )

这两个设置不可能是一回事。

STATICFILES_DIR没问题,如果多余您的STATICFILES_FINDERS已告诉它在每个应用的static目录中找到静态文件,请执行以下操作:'django.contrib.staticfiles.finders.AppDirectoriesFinder',

STATIC_ROOT的目的是提供一个与您的项目完全分开的新目录,您可以将其与第三方服务器(如nginx)一起提供。这就是您创建该目录staticfiles

的原因
STATIC_ROOT = os.path.join(os.getcwd(),'staticfiles')

另一个编辑

临时文件系统的解决方法

  

每个dyno都有自己的短暂文件系统,并带有最近部署代码的全新副本。在dyno的生命周期中,其运行进程可以将文件系统用作临时暂存器,但是任何其他dyno中的进程都不会看到所写的文件,并且在dyno停止或重新启动时,所写的任何文件都将被丢弃。

这意味着只要您在网络启动期间在每个dyno实例上收集静态,就不会有任何问题。

web: python myproject_django/manage.py collectstatic --noinput; python myproject_django/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 3

那就是说,我目前使用S3和django存储http://django-storages.readthedocs.org/en/latest/index.html。这很容易(也很便宜)。

答案 1 :(得分:4)

有一种解决方案。

在urls.py中添加:

from django.conf import settings

urlpatterns += patterns('',
    (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
)

P.S。对于STATIC_URL = '/static/'

答案 2 :(得分:1)

使用run_collectstatic脚本作为heroku-django-cookbook提供的post_compile的一部分运行。它使用了Heroku python buildpack提供的post_compile钩子

答案 3 :(得分:1)

我遇到了同样的问题;看来你需要特别需要这三个设置:

    必须在STATIC_ROOT中定义
  1. settings.py,例如:

    STATIC_ROOT = os.path.join(PROJECT_PATH, 'served/static/')
    

    PROJECT_PATH是您的项目根目录(在您的情况下,是myproject_django目录的绝对路径。

  2. 同样,还必须设置STATIC_URL(如果不这样,Django将抛出一个ErrorperlyConfigured错误)。您当前的'/static/'设置很好。

  3. 在根目录urls.py中,配置静态网址:

    from django.conf import settings
    from django.conf.urls.static import static  
    
    ...
    
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    
  4. 最后,运行python manage.py collectstatic;这会将所有文件从/path/to/site-packages/django/contrib/admin/static/admin/复制到/served/static/。 (您可以阅读有关Django如何提供静态文件here)的更多信息。

    现在,当您运行foreman start时,您应该看到带有样式的管理员。

    不要忘记将served/static/添加到.gitignore

答案 4 :(得分:0)

我发现here很好的方法来解决我在heroku上使用Django的所有问题