将 Django 部署到 AWS;傻瓜静态文件

Deploying Django to AWS; static files for dummies

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

到目前为止,我已经能够开发一个在本地主机上按我希望的方式工作的 django 应用程序;我已经能够将该网站部署到 AWS EC2,但我一定遗漏了一些有关提供静态文件的基本知识。 (我什至还没有尝试过媒体文件。)我读过 Django Deployment page and How-To manage static files,但我以前从未从头开始部署过网站。我发现的教程似乎自相矛盾(或已过时?)。

以下是我认为我此时的问题:

  1. 需要在存储桶中托管静态(and/or 媒体)文件,还是这只是个好主意?
  2. 当我设置 STATIC_ROOT 和 STATIC_URL 时,我应该设置 STATICFILE_DIRS 吗? (我的意思是,我认为我真的需要一个关于它们如何组合在一起、它们的设置以及 'static' 在模板中如何工作的教程。)
  3. 我试着让 whitenoise 开始;我收到一条消息,提示 STATIC_URL 设置不正确;我找不到文档来告诉我它应该是什么。这是一个可行的根吗?

编辑

即使@DirkGroten 的回答非常详细,我仍然不知道如何提供静态文件。我可以 运行 服务器,然后通过网络浏览器查看没有静态文件的页面。但是,我现在遇到了一个新问题:上面有静态文件的页面 return 出现 500 27 错误(而他们过去常常 return 只有文件出现错误)。所以,这是我的文件夹结构,下面是我的设置文件的相关部分(实际上分为 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。

首先你的问题:

  1. 不,这是选项之一,但使用集中式共享存储绝对是个好主意,因为当您需要从多个 EC2 实例为您的站点提供服务时。 S3 是一种选择,我使用 EFS,我发现它更容易(见下文)。
  2. 是的,您需要告诉 collectstatic 在哪里可以找到静态文件,因此您应该 STATICFILES_DIRS.
  3. 是的,我喜欢 whitenoise,它与 CDN 结合使用效果很好。更容易不用担心 expiry/cache headers.

我写了一篇blog post about this

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

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

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

  • 存储在所有 EC2 实例安装和共享的 EFS 卷上的静态文件(比 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)。