将 Django 部署到 AWS;傻瓜静态文件
Deploying Django to AWS; static files for dummies
我完全迷失在这个项目的最后一步中。
到目前为止,我已经能够开发一个在本地主机上按我希望的方式工作的 django 应用程序;我已经能够将该网站部署到 AWS EC2,但我一定遗漏了一些有关提供静态文件的基本知识。 (我什至还没有尝试过媒体文件。)我读过 Django Deployment page and How-To manage static files,但我以前从未从头开始部署过网站。我发现的教程似乎自相矛盾(或已过时?)。
以下是我认为我此时的问题:
- 我需要在存储桶中托管静态(and/or 媒体)文件,还是这只是个好主意?
- 当我设置 STATIC_ROOT 和 STATIC_URL 时,我应该设置 STATICFILE_DIRS 吗? (我的意思是,我认为我真的需要一个关于它们如何组合在一起、它们的设置以及 'static' 在模板中如何工作的教程。)
- 我试着让 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。
首先你的问题:
- 不,这是选项之一,但使用集中式共享存储绝对是个好主意,因为当您需要从多个 EC2 实例为您的站点提供服务时。 S3 是一种选择,我使用 EFS,我发现它更容易(见下文)。
- 是的,您需要告诉
collectstatic
在哪里可以找到静态文件,因此您应该 STATICFILES_DIRS
.
- 是的,我喜欢 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)。
我完全迷失在这个项目的最后一步中。
到目前为止,我已经能够开发一个在本地主机上按我希望的方式工作的 django 应用程序;我已经能够将该网站部署到 AWS EC2,但我一定遗漏了一些有关提供静态文件的基本知识。 (我什至还没有尝试过媒体文件。)我读过 Django Deployment page and How-To manage static files,但我以前从未从头开始部署过网站。我发现的教程似乎自相矛盾(或已过时?)。
以下是我认为我此时的问题:
- 我需要在存储桶中托管静态(and/or 媒体)文件,还是这只是个好主意?
- 当我设置 STATIC_ROOT 和 STATIC_URL 时,我应该设置 STATICFILE_DIRS 吗? (我的意思是,我认为我真的需要一个关于它们如何组合在一起、它们的设置以及 'static' 在模板中如何工作的教程。)
- 我试着让 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。
首先你的问题:
- 不,这是选项之一,但使用集中式共享存储绝对是个好主意,因为当您需要从多个 EC2 实例为您的站点提供服务时。 S3 是一种选择,我使用 EFS,我发现它更容易(见下文)。
- 是的,您需要告诉
collectstatic
在哪里可以找到静态文件,因此您应该STATICFILES_DIRS
. - 是的,我喜欢 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)。