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

时间:2023-01-07 19:16:38

My Django 1.3 project serves the static files on a development server but with the gunicorn server static files are not served. I followed the steps of this Heroku guide.

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

When I used the contents of my procfile like in the guide ( web: gunicorn myproject_django.wsgi -b 0.0.0.0:$PORT) my project was not recognised by Heroku.

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

Then I changed that Procfile to this:

然后我将Procfile更改为:

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

Now my app runs except for the static files(css not active nor images).

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

My project tree:

我的项目树:

.
├── 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

Potentially relevant parts of settings.py

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',
)

Edit

I adjusted the following things after Francis Yaconiello's entry:

Francis Yaconiello进入后我调整了以下内容:

In settings.py

在settings.py中

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

In gitignore:

在gitignore:

staticfiles/*

Then commited. And finally ran heroku run python myproject_django/manage.py collectstatic.

然后承诺。最后运行heroku运行python myproject_django / manage.py collectstatic。

But static files are still not served when I check the webpage. Given my directory tree why didn't these changes work?

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

Edit2

I still don't see my static files. When I click on an image while DEBUG=True I get this:

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

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

Tree (Note that the staticfiles dir is empty)

树(请注意,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

In settings.py

在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 个解决方案

#1


5  

Specify your STATIC_ROOT

指定您的STATIC_ROOT

I generally set it to :

我通常把它设置为:

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

create that directory in your project

在项目中创建该目录

mkdir staticfiles

make sure that the contents of staticfiles is not git tracked

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

nano .gitignore

add

staticfiles/*

then commit it and push to heroku.

然后提交它并推送到heroku。

lastly,

最后,

heroku run python manage.py collectstatic

EDIT

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

These two settings cannot be the same thing.

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

STATICFILES_DIR is OK, if redundant your STATICFILES_FINDERS already is telling it to find staticfiles in the static directory of each app with this: 'django.contrib.staticfiles.finders.AppDirectoriesFinder',

STATICFILES_DIR是好的,如果多余,你的STATICFILES_FINDERS已告诉它在每个应用程序的静态目录中找到静态文件:'django.contrib.staticfiles.finders.AppDirectoriesFinder',

The point of STATIC_ROOT is to provide a new directory completely separate from your project that you can serve with a third party server like nginx. Which is why you created that directory staticfiles:

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

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

ANOTHER EDIT

workaround for ephemeral filesystem

临时文件系统的解决方法

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

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

which means that as long as you collectstatic on each dyno instance during web startup, you won't have any issues.

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

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

That said, I currently use S3 and django storages http://django-storages.readthedocs.org/en/latest/index.html. Its fairly easy (and cheap) to get this going.

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

#2


4  

There is one solution.

有一个解决方案。

In urls.py add:

在urls.py中添加:

from django.conf import settings

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

p.s. For STATIC_URL = '/static/'

附:对于STATIC_URL ='/ static /'

#3


1  

Use the run_collectstatic script which run as part of the post_compile provided by heroku-django-cookbook. It makes use of the post_compile hook provided by the Heroku python buildpack

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

#4


1  

I ran into the same problem; it seems you need these three settings in particular:

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

  1. STATIC_ROOT must be defined in your settings.py, for example:

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

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

    Where PROJECT_PATH is your project root (in your case, the absolute path to the myproject_django directory.

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

  2. Similarly, STATIC_URL must also be set (Django will throw an ImproperlyConfigured error anyway, if you don't). Your current setting of '/static/' is fine.

    类似地,还必须设置STATIC_URL(如果不这样,Django将抛出一个不正确配置的错误)。你当前的'/ static /'设置没问题。

  3. In your root urls.py, configure the static urls:

    在你的root urls.py中,配置静态URL:

    from django.conf import settings
    from django.conf.urls.static import static  
    
    ...
    
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    

Finally, run python manage.py collectstatic; this will copy all the files from /path/to/site-packages/django/contrib/admin/static/admin/ to /served/static/. (You can read more about how Django serves static files here).

最后,运行python manage.py collectstatic;这会将/ path /中的所有文件复制到/ site-packages / django / contrib / admin / static / admin /到/ serve / static /。 (您可以在此处阅读有关Django如何提供静态文件的更多信息)。

Now when you run foreman start, you should see the admin with styling.

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

Don't forget to add served/static/ to your .gitignore!

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

#5


0  

I found here good way to resolve all my problems with Django on heroku

我在这里找到了解决我在heroku上使用Django的所有问题的好方法

#1


5  

Specify your STATIC_ROOT

指定您的STATIC_ROOT

I generally set it to :

我通常把它设置为:

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

create that directory in your project

在项目中创建该目录

mkdir staticfiles

make sure that the contents of staticfiles is not git tracked

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

nano .gitignore

add

staticfiles/*

then commit it and push to heroku.

然后提交它并推送到heroku。

lastly,

最后,

heroku run python manage.py collectstatic

EDIT

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

These two settings cannot be the same thing.

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

STATICFILES_DIR is OK, if redundant your STATICFILES_FINDERS already is telling it to find staticfiles in the static directory of each app with this: 'django.contrib.staticfiles.finders.AppDirectoriesFinder',

STATICFILES_DIR是好的,如果多余,你的STATICFILES_FINDERS已告诉它在每个应用程序的静态目录中找到静态文件:'django.contrib.staticfiles.finders.AppDirectoriesFinder',

The point of STATIC_ROOT is to provide a new directory completely separate from your project that you can serve with a third party server like nginx. Which is why you created that directory staticfiles:

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

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

ANOTHER EDIT

workaround for ephemeral filesystem

临时文件系统的解决方法

Each dyno gets its own ephemeral filesystem, with a fresh copy of the most recently deployed code. During the dyno’s lifetime its running processes can use the filesystem as a temporary scratchpad, but no files that are written are visible to processes in any other dyno and any files written will be discarded the moment the dyno is stopped or restarted.

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

which means that as long as you collectstatic on each dyno instance during web startup, you won't have any issues.

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

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

That said, I currently use S3 and django storages http://django-storages.readthedocs.org/en/latest/index.html. Its fairly easy (and cheap) to get this going.

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

#2


4  

There is one solution.

有一个解决方案。

In urls.py add:

在urls.py中添加:

from django.conf import settings

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

p.s. For STATIC_URL = '/static/'

附:对于STATIC_URL ='/ static /'

#3


1  

Use the run_collectstatic script which run as part of the post_compile provided by heroku-django-cookbook. It makes use of the post_compile hook provided by the Heroku python buildpack

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

#4


1  

I ran into the same problem; it seems you need these three settings in particular:

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

  1. STATIC_ROOT must be defined in your settings.py, for example:

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

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

    Where PROJECT_PATH is your project root (in your case, the absolute path to the myproject_django directory.

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

  2. Similarly, STATIC_URL must also be set (Django will throw an ImproperlyConfigured error anyway, if you don't). Your current setting of '/static/' is fine.

    类似地,还必须设置STATIC_URL(如果不这样,Django将抛出一个不正确配置的错误)。你当前的'/ static /'设置没问题。

  3. In your root urls.py, configure the static urls:

    在你的root urls.py中,配置静态URL:

    from django.conf import settings
    from django.conf.urls.static import static  
    
    ...
    
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    

Finally, run python manage.py collectstatic; this will copy all the files from /path/to/site-packages/django/contrib/admin/static/admin/ to /served/static/. (You can read more about how Django serves static files here).

最后,运行python manage.py collectstatic;这会将/ path /中的所有文件复制到/ site-packages / django / contrib / admin / static / admin /到/ serve / static /。 (您可以在此处阅读有关Django如何提供静态文件的更多信息)。

Now when you run foreman start, you should see the admin with styling.

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

Don't forget to add served/static/ to your .gitignore!

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

#5


0  

I found here good way to resolve all my problems with Django on heroku

我在这里找到了解决我在heroku上使用Django的所有问题的好方法