将Django部署到AWS;静态虚拟文件 [英] Deploying Django to AWS; static files for dummies

查看:74
本文介绍了将Django部署到AWS;静态虚拟文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

到目前为止,我已经能够开发django应用程序,该应用程序可以按我希望的方式在localhost上运行;我已经可以将网站部署到AWS EC2,但是我必须缺少有关提供静态文件的基本知识. (我什至还没有尝试过媒体文件.)我已经阅读了Django 部署页面和操作方法静态文件,但我以前从未从头开始部署过网站.我发现的教程似乎相互矛盾(或已过时?).

这是我目前遇到的问题:

  1. 需要在存储桶中托管静态(和/或媒体)文件,还是一个好主意?
  2. 设置STATIC_ROOT和STATIC_URL时,应该设置STATICFILE_DIRS吗? (我的意思是,我认为我确实需要一个关于它们甚至如何一起使用,它们的设置以及模板中静态"如何工作的教程.)
  3. 我试图消除白噪声;我收到一条消息,指示STATIC_URL设置不正确;我找不到文档来告诉我应该是什么.这是可行的根源吗?

编辑

即使使用@DirkGroten的惊人的详细答案,我仍然没有得到如何提供静态文件的信息.我可以先运行服务器,然后再运行Web浏览器,以查看没有静态文件的页面.但是,我现在遇到了一个新问题:在其上具有静态文件的页面返回500 27错误(而它们过去仅对文件返回错误).因此,这是我的文件夹结构,下面是我的设置文件(实际上分为基础,开发和生产)的相关部分.

[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'

我已经确保要在生产需求文件中导入白噪声.

我想念什么?

此外,我从未使用过AWS支持系统. (我是免费会员.)这是我可以得到他们帮助的事情吗?我要开始案件吗?

TIA.

解决方案

首先提出您的问题:

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

我写了一个,其中BASE_DIR(在某些项目中为PROJECT_ROOT)是项目的根目录.

  • STATIC_ROOT应该是磁盘上静态文件的物理位置.这是collectstatic将它们复制并索引的地方,从BASE_DIR(即os.path.abspath(os.path.join(BASE_DIR, '../static'))
  • )开始

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

    如果您可以使用它,请开始添加CDN(将其设置为从服务器获取文件,whitenoise现在只需将每个文件提供给CDN,浏览器便会从CDN获取它);您需要更改STATIC_URL以添加CDN的主机名(例如https://die9493v4034.cloudfront.net/static/).

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

    I am utterly lost on one of the last steps of this project.

    So far, I've been able to develop a django app that works the way I want it to on localhost; I've been able to deploy the website to AWS EC2, but I must be missing something fundamental about serving the static files. (I haven't even tried media files yet.) I've read the Django Deployment page and How-To manage static files, but I have never deployed a website from scratch before. The tutorials I've found seem to be contradicting (or outdated?).

    Here are the questions I think I have at this time:

    1. Do I need to host static (and/or media) files in a bucket, or is this merely a good idea?
    2. When I set up STATIC_ROOT and STATIC_URL, should I have a STATICFILE_DIRS setup? (I mean, I think I really need a tutorial on how they even go together, their settings, and how 'static' works in the templates.)
    3. I've tried to get whitenoise going; I get a message that STATIC_URL isn't set up correctly; I can't find the documentation to tell me what it should be. Is this a viable root to take?

    EDIT

    Even with @DirkGroten 's amazingly detailed answer, I'm still not getting how to serve static files. I can run the server and then web browser in to see pages with no static files. But, I now have a new problem: Pages that have static files on them return a 500 27 error (whereas they used to return an error for only the file). So, here is my folder structure, and below that is the relevant part of my settings file (which is actually split into base, dev, and 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)
    

    development settings:

    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'
    

    I have made sure that I am importing whitnoise in production requirements file.

    What am I missing?

    Also, I have never used the AWS support system. (I'm on the free tier.) Is this the kind of thing I can get their help on? Do I start a case?

    TIA.

    解决方案

    First your questions:

    1. No, it's one of the options, but it's definitely a good idea to use a centralised, shared storage, for when you'll need to serve your site from multiple EC2 instances. S3 is one option, I use EFS which I find easier (see below).
    2. Yes, you need to tell collectstatic where to find the static files so you should have STATICFILES_DIRS.
    3. Yes, I like whitenoise, it works well in combination with a CDN. Makes it easier not to worry about expiry/cache headers.

    I've written a blog post about this.

    This is a setup that works for one EC2 instance:

    • Static files stored locally on the EC2 instance (on the EBS volume) -> STATIC_ROOT setting (where are they stored)
    • Whitenoise to serve the static files and setting cache headers correctly
    • CompressedManifestStaticFilesStorage as the storage (STATICFILES_STORAGE setting)
    • Preferably CloudFront or other CDN to serve the static files -> STATIC_URL setting.

    Eventually you'll want to have your static files stored centrally so that multiple EC2 instances can access them (otherwise you'd have to duplicate them on each machine and ensure the manifest files are in sync), so my own setup is:

    • Static files stored on an EFS volume that is mounted and shared by all EC2 instances (much easier to setup and use than S3, as it's just a mounted disk as far as python is concerned). I set the mount point of the EFS volume to be the same location as STATIC_ROOT, so nothing to change in settings.
    • Then the same as above: Whitenoise, CloudFront and the manifest storage.

    Try first to get it to work with the first setup, doing the following:

    • STATIC_URL should be the URL that will show up in the HTML. Just /static/ should work with WhiteNoiseMiddleware but if you use a CDN, you need to precede that with the full host name of your CDN instance.
    • STATICFILES_STORAGE should be one of the storages offered by Whitenoise, I recommend CompressedManifestStaticFilesStorage.
    • STATICFILES_DIRS tells collectstatic where it can find the static files to collect. Note that if you only have static files in a /static directory inside each app, collectstatic will find them automatically, and you should not specify those directories here. If you have a /static directory in your main project directory, you should add (os.path.join(BASE_DIR, "my_site", "static"),) to STATICFILES_DIRS where BASE_DIR (or PROJECT_ROOT in some projects) is the root directory of your project.
    • STATIC_ROOT should be the physical location of the static files on disk. This is where collectstatic will copy them and index them, start with on level up from your BASE_DIR, i.e. os.path.abspath(os.path.join(BASE_DIR, '../static'))

    Now every time you update your code and static files, you should run django-admin collectstatic. This will copy all your static files to your STATIC_ROOT directory where whitenoise will fetch them to serve them. You'll see MD5 hashes added to the filename each time the file changes, this is so that browsers fetch the new version and don't use the cached version (Whitenoise tells browsers to cache static files for 2 years by default).

    If you get this to work, start adding a CDN (set it up so it fetches the files from your server, whitenoise now will only have to serve each file once to the CDN, browsers will get it from the CDN); you'll need to change STATIC_URL to add the CDN's host name (e.g. https://die9493v4034.cloudfront.net/static/).

    Then move the location of the files from the local instance to a shared storage (e.g. EFS).

    这篇关于将Django部署到AWS;静态虚拟文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆