【问题标题】:Deploying Django to AWS; static files for dummies将 Django 部署到 AWS;假人的静态文件
【发布时间】:2019-05-15 03:53:53
【问题描述】:

我完全迷失了这个项目的最后一步。

到目前为止,我已经能够开发出一个 django 应用程序,它可以按照我希望的方式在 localhost 上运行;我已经能够将网站部署到 AWS EC2,但我必须缺少一些关于提供静态文件的基本知识。 (我什至还没有尝试过媒体文件。)我已经阅读了 Django Deployment page 和 How-To manage static files,但我以前从未从头开始部署过网站。我发现的教程似乎相互矛盾(或过时?)。

以下是我想我此时的问题:

  1. 我是否需要在存储桶中托管静态(和/或媒体)文件,或者这仅仅是一个好主意?
  2. 当我设置 STATIC_ROOT 和 STATIC_URL 时,我应该设置 STATICFILE_DIRS 吗? (我的意思是,我认为我真的需要一个关于它们如何组合、它们的设置以及“静态”在模板中如何工作的教程。)
  3. 我试图让白噪声继续运行;我收到一条消息,指出 STATIC_URL 设置不正确;我找不到文档来告诉我它应该是什么。这是一个可行的根吗?

编辑

即使@DirkGroten 给出了非常详细的答案,我仍然不知道如何提供静态文件。我可以运行服务器,然后运行 ​​Web 浏览器来查看没有静态文件的页面。但是,我现在遇到了一个新问题:上面有静态文件的页面会返回 500 27 错误(而它们过去只为文件返回错误)。所以,这是我的文件夹结构,下面是我的设置文件的相关部分(实际上分为 base、dev 和 prod)。

[mainsite]/
|---[mainsite]/
|   |---[settings]/
|       |---base.py
|       |---dev.py
|       |---prod.py
|---[app1]/
|   |---[migrations]
|   |---[static]/
|   |   |---[app1]/
|   |   |   |---app1_file1.jpg (etc)
|   |   |---app1_style.css
|   |---[templates]/
|   |   |---[app1]/
|   |       |---about.html (etc)
|---[app2]/ (etc)
|---[static]  (this gets populated after running collectstatic)

开发设置:

Debug = False
ALLOWED_HOSTS = [###.###.###.###]  

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',   
... (the rest of the middleware)
]

STATIC_URL = '/static/'
STATIC_ROOT = os.path.abspath(os.path.join(BASE_DIR, 'static'))
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'app1/'),
                    os.path.join(BASE_DIR, 'app2/'),
                    os.path.join(BASE_DIR, 'app3/'),
                    ]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

我已确定我在生产需求文件中导入了 whitnoise。

我错过了什么?

另外,我从未使用过 AWS 支持系统。 (我在免费套餐上。)这是我可以得到他们帮助的事情吗?我要立案吗?

TIA。

【问题讨论】:

    标签: django amazon-web-services django-staticfiles static-files


    【解决方案1】:

    首先你的问题:

    1. 不,这是选项之一,但当您需要从多个 EC2 实例为您的站点提供服务时,使用集中式共享存储绝对是一个好主意。 S3 是一种选择,我使用 EFS,我觉得它更容易(见下文)。
    2. 是的,您需要告诉collectstatic 在哪里可以找到静态文件,这样您就应该拥有STATICFILES_DIRS
    3. 是的,我喜欢白噪声,它与 CDN 结合使用效果很好。让您更轻松地不必担心过期/缓存标头。

    我写了blog post about this

    这是一种适用于一个 EC2 实例的设置:

    • 静态文件本地存储在 EC2 实例上(在 EBS 卷上)-> STATIC_ROOT 设置(它们存储在哪里)
    • Whitenoise 为静态文件提供服务并正确设置缓存头
    • CompressedManifestStaticFilesStorage 作为存储(STATICFILES_STORAGE 设置)
    • 最好使用 CloudFront 或其他 CDN 来提供静态文件 -> STATIC_URL 设置。

    最终您会希望将静态文件集中存储,以便多个 EC2 实例可以访问它们(否则您必须在每台机器上复制它们并确保清单文件同步),所以我自己的设置是:

    • 存储在 EFS 卷上的静态文件,所有 EC2 实例都挂载和共享(比 S3 更容易设置和使用,因为就 python 而言,它只是一个挂载的磁盘)。我将 EFS 卷的挂载点设置为与 STATIC_ROOT 相同的位置,因此无需更改设置。
    • 然后同上:Whitenoise、CloudFront 和清单存储。

    首先尝试让它与第一个设置一起工作,执行以下操作:

    • STATIC_URL 应该是显示在 HTML 中的 URL。只需 /static/ 即可与 WhiteNoiseMiddleware 一起使用,但如果您使用 CDN,则需要在其前面加上 CDN 实例的完整主机名。
    • STATICFILES_STORAGE应该是Whitenoise提供的存储之一,我推荐CompressedManifestStaticFilesStorage
    • STATICFILES_DIRS 告诉collectstatic 在哪里可以找到要收集的静态文件。请注意,如果您在每个应用程序内的 /static 目录中只有静态文件,collectstatic 将自动找到它们,您不应在此处指定这些目录。如果您的项目主目录中有/static 目录,则应将(os.path.join(BASE_DIR, "my_site", "static"),) 添加到STATICFILES_DIRS,其中BASE_DIR(或在某些项目中为PROJECT_ROOT)是项目的根目录。
    • STATIC_ROOT 应该是磁盘上静态文件的物理位置。这是collectstatic 将复制它们并索引它们的地方,从你的BASE_DIR 开始,即os.path.abspath(os.path.join(BASE_DIR, '../static'))

    现在每次更新代码和静态文件时,都应该运行django-admin collectstatic。这会将您的所有静态文件复制到您的STATIC_ROOT 目录,whitenoise 将在其中获取它们以提供服务。每次文件更改时,您都会看到文件名中添加了 MD5 哈希,这样浏览器可以获取新版本而不使用缓存版本(Whitenoise 告诉浏览器默认缓存静态文件 2 年)。

    如果你让它工作,开始添加一个 CDN(设置它以便它从你的服务器获取文件,whitenoise 现在只需将每个文件提供给 CDN 一次,浏览器将从 CDN 获取它);您需要更改 STATIC_URL 以添加 CDN 的主机名(例如 https://die9493v4034.cloudfront.net/static/)。

    然后将文件的位置从本地实例移动到共享存储(例如 EFS)。

    【讨论】:

    • 我不想一直打扰你,但我无法让你的解决方案发挥作用。我已经编辑了我的问题以包含代码。你能说出我错过了什么吗?
    • 尝试查看日志,看看 500 错误是什么。如果您的生产机器上没有日志,您将很难解决问题。一个可能的 500 错误可能是在 staticfiles.json 中找不到文件的条目。如果您忘记 collectstatic 然后重新启动服务器,就会发生这种情况。或者如果 collectstatic 没有收集您的所有文件。
    • 如果您的所有静态文件都在每个注册应用程序的“静态”目录中,则无需指定STATICFILES_DIRS。只有当它们位于其他地方时(例如,如果你在mainsite 中有一些)你才需要这个。在您的情况下,我认为这可能会弄乱 STATIC_ROOT 目录中的路径。
    • 如果可以,检查顶部 /static 目录(由 collectstatic 创建)中是否有模板中引用的文件(例如 {% static 'app1/app1_file1.jpg' %})您有一个位于完全相同路径的文件(所以在mainsite/static/app1/app1_file1.jpg).
    • 好吧,我没有得到这个解决方案,但我确实得到了一个在 s3 上运行的存储桶。感谢您的时间和帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-04-16
    • 2021-08-22
    • 2014-05-26
    • 2014-06-08
    • 2012-06-09
    • 2016-03-11
    • 2022-11-01
    • 2020-07-06
    相关资源
    最近更新 更多