亚马逊弹性Beanstalk无法提供Django静态文件

26
我正在尝试在弹性Beanstalk上建立一个简单的Django应用程序。我认为我已经解决了应用程序的静态部分,因为它在Heroku和手动设置的服务器上运行良好。在调试中,我甚至检查并推送了静态目录中的静态文件,以尝试简化事情。映射似乎非常奇怪,因为它似乎不遵循STATIC_ROOT。
我的相关配置: settings.py
PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
STATIC_ROOT = os.path.join(PROJECT_ROOT,'static/')
STATIC_URL = '/static/'
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

urls.py

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

记录:

[Wed Dec 26 15:39:04 2012] [error] [client 10.29.203.20] File does not exist: /opt/python/current/app/css, referer 10.29.203.20 - - 
[26/Dec/2012:15:39:04 +0000] "GET /static/css/styles.css HTTP/1.1" 404 329 "http://" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11"
9个回答

35

提醒大家,最近的EBS版本中静态文件的命名空间已更改为aws:elasticbeanstalk:environment:proxy:staticfiles,如下所示:

option_settings:
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static

是的,这对我也适用于新的Amazon Linux 2实例 https://docs.amazonaws.cn/en_us/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-environmentproxystaticfiles - Simone
1
这对我有效,根据 Elastic Beanstalk 最新更新的 Django 文档,我在 .ebextensions 文件夹中更新了 Django.config 文件。 - Mayur Gupta

25

今天我遇到了同样的问题,后来发现我在.ebextensions/.config文件中忘记添加这个选项。请确保你也有这个选项。

option_settings:
  - namespace: aws:elasticbeanstalk:container:python:staticfiles
    option_name: /static/
    value: static/

13
为了让它更加清晰明了:static/ 这个值指的是您的静态文件所在的文件夹。在我的情况下,那是 app/static,这也让我想知道为什么 static/ 不能正常工作。 - Felix
2
我遇到了语法错误...这似乎是新的语法:option_settings: "aws:elasticbeanstalk:container:python:staticfiles": /static/: "app/static/"但我认为这不是最优解,因为它似乎只适用于特定的应用程序。 - Anis Abboud
1
如果有几个应用程序,每个应用程序都有自己的“static”目录,这是否有效? - MadPhysicist
求助!我该如何在 Elastic Beanstalk 上处理一个多容器 Django 应用程序?我最关心的是这一行:namespace: aws:elasticbeanstalk:container:python:staticfiles - Mwibutsa Floribert

18
运行collectstatic可以支持多个应用程序。
Settings.py
STATIC_ROOT = os.path.join(BASE_DIR, "static")

请确保您的根目录下有一个名为“static”的文件夹。

在您的EBS配置文件中,例如(02_python.config或类似文件)。

option_settings:
    ...
    "aws:elasticbeanstalk:container:python:staticfiles":
        /static/: "static/"

在上传到 EBS 之前,请先执行 python manage.py collectstatic

此命令将所有静态文件收集到一个文件夹中,该文件夹已在您的配置中指定。

然后像往常一样运行eb deploy

如果您不想将静态文件提交到源代码控制两次,并希望服务器代替您执行此操作,请将以下内容添加到您的配置文件中(非必需)

container_commands:
01_collectstatic:
    command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput"

所以您的文件应该长这样:

container_commands:
01_collectstatic:
  command: "source /opt/python/run/venv/bin/activate && python manage.py collectstatic --noinput"


option_settings:
    "aws:elasticbeanstalk:container:python":
      WSGIPath: app/wsgi.py
    "aws:elasticbeanstalk:container:python:staticfiles":
      /static/: "static/"

当你运行eb deploy时,这将为您运行collect static


有了这个,静态文件现在可以加载了,但是我得到了一个container_commands条目: '.ebextensions/django.config' - 包含无效的键:'01_collectstatic'。 阅读文档并不清楚如何处理它们。然而,这些示例正在帮助解决问题:https://github.com/awsdocs/elastic-beanstalk-samples/blob/9720e38e9da155752dce132a31d8e13a27364b83/configuration-files/aws-provided/instance-configuration/awslogs-change-frequency.config#L56 - JohnZaj

13
如果您的环境使用基于Amazon Linux 2的平台分支,则应在.ebextensions文件夹内的.config文件中设置正确的配置。
aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static

在您的项目 settings.py 中,应该有:

STATIC_URL = '/static/'
STATIC_ROOT = 'static'

你解决了我4小时的问题。这个答案对我来说完美地起作用了。 请注意,“Amazon Linux 2”实例。 - Jay Lim
1
对于我来说,没有撇号是不起作用的。应该是"/static/": "static"。 - cuneyttyler

7

对我而言,问题在于拥有过多的

STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static')

相反,我将其更改为

STATIC_ROOT = 'static'

此外,我的.conf文件中有以下内容:
option_settings:
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"

为什么 os.path.join(os.path.dirname(__file__), 'static') 是错误的? - kansiho

2

顺便提一下,我的设置如下: STATIC_URL = '/static/' STATIC_ROOT = 'static'

STATIC_ROOT = os.path.join(BASE_DIR, "static")

STATICFILES_DIRS = (

os.path.join(BASE_DIR, "static"),

)

- quinn li

2

之前的所有答案都没有帮到我,但是这个方法对我有效。

基本上,我在 .ebextensions 文件夹中创建了两个步骤。

01_django.config

container_commands:
    01_migrate:
        command: "source /opt/python/current/env && source /opt/python/run/venv/bin/activate && cd /opt/python/current/app && python manage.py migrate --noinput"
        leader_only: true
    02_touch_superuser:
        command: "source /opt/python/current/env && source /opt/python/run/venv/bin/activate && cd /opt/python/current/app && python manage.py touch_superuser"
        leader_only: true
option_settings:
    aws:elasticbeanstalk:container:python:
        WSGIPath: config/wsgi.py
        NumProcesses: 2
        NumThreads: 10
    aws:elasticbeanstalk:application:environment:
        STAGING: 1
        DJANGO_SETTINGS_MODULE: config.settings.production
    aws:elasticbeanstalk:container:python:staticfiles:
        "/static/": "htdocs/static/"
        "/media/": "htdocs/media/"

config/wsgi.py 可能在您的项目中是不同的路径

02_collec_static.config

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/10_collect_static.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      set -xe

      source /opt/python/current/env
      source /opt/python/run/venv/bin/activate
      cd /opt/python/current/app && python manage.py collectstatic --noinput

      echo "Statics collected...!!"

重要的一点是,你的settings/*.py文件应该与EBS提供的静态路径相匹配,对我而言,这是我的配置。

...
PROJECT_PATH = dirname(dirname(dirname(__file__)))
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'htdocs/media')
STATIC_ROOT = os.path.join(PROJECT_PATH, 'htdocs/static')
...

1

我在这个问题上挣扎了相当长的一段时间,一直认为问题出在 :

option_settings:
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"

但实际上,我的问题在于xxx.config文件中的其他命令。基本上,请确保其他行是正确的。
如果您想了解我的个人设置,我使用了上面显示的设置文件,并在项目的根目录中添加了静态目录。 对于settings.py文件,这是我为static_url和root所拥有的内容:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = 'static'

希望它有所帮助!

1

我采取了以下步骤来解决Beanstalk中的静态路径问题

STATIC_URL = '/static/'

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

option_settings:
  ...
  ...
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"

谢谢。但对于我来说(AWS Elastic Beanstalk),我需要执行 STATIC_ROOT = 'static' - Chris Merck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接