【问题标题】:Django collectstatic from Heroku pushes to S3 everytime每次从 Heroku 推送到 S3 的 Django collectstatic
【发布时间】:2013-01-03 05:59:10
【问题描述】:

我将 django-storages 用于 S3(和 S3BotoStorage)的静态文件。当我从本地机器执行 collectstatic 时,行为符合预期,仅将修改后的文件推送到 S3。这个过程需要python-dateutils 1.5来检查修改时间。

但是,在 Heroku 上执行相同操作会导致每个文件都被推送,尽管设置是相同的。然后我查看了 Heroku 本身文件的修改时间,似乎 os.stat(static_filename).st_mtime 与上次推送的时间相同。

这是预期的行为吗?即使 git 没有变化,heroku 是否会复制文件?

【问题讨论】:

    标签: django heroku django-storage


    【解决方案1】:

    尝试将 DISABLE_COLLECTSTATIC=1 设置为您的应用的环境设置 - 这应该会禁止它在每次推送时运行。

    详情请看这篇文章-https://devcenter.heroku.com/articles/django-assets

    > Sometimes, you may not want Heroku to run collectstatic on your behalf.
    > You can disable collectstatic by enabling user-env-compile as well:
    
    $ heroku labs:enable user-env-compile
    $ heroku config:set DISABLE_COLLECTSTATIC=1
    

    我发现只需设置配置即可 - 无需同时启用 user-env-compile - 这可能是已从实验室转入生产?

    注意,部署由 Heroku python buildpack 管理,您可以在此处查看 - https://github.com/heroku/heroku-buildpack-python/

    编辑 1

    我刚刚对此进行了一系列测试,并且可以确认DISABLE_COLLECTSTATIC 确实禁用了collectstatic,无论user-env-compile 设置如何 - 我认为它现在位于主干线中(但这是推测)。似乎并不关心设置是什么 - 如果 DISABLE_COLLECTSTATIC 作为配置变量存在,它会被使用。

    【讨论】:

      【解决方案2】:

      我强烈建议将collectfast package 用于任何到 s3 的 django 静态部署,无论是本地还是从您的 heroku 服务器。它忽略修改的日期并利用 md5 哈希,s3 api 将非常快速地提供这些哈希,以及(可选)缓存以使您的静态部署缩放。我的静态部署从大约 10-15 分钟到

      【讨论】:

      • 谢谢!会试一试的。
      【解决方案3】:

      我刚刚遇到了同样的问题,并联系了 Heroku 的支持人员以了解发生了什么。我对他们的问题是

      我在进行一些部署时遇到了一个时髦的问题。似乎在每次推送时,所有文件的修改日期都会更新为新的部署/git推送发生的时间。这是预期的行为吗?

      考虑到 Django 的 collectstatic 命令在评估是否应将文件复制到静态资产的最终存储后端时仅检查文件的修改日期,这意味着在每次新推送时,首先从远程存储(在本例中为 S3),然后重新上传。就带宽消耗和请求而言,这是一个非常缓慢和浪费的过程。

      我今天从 Heroku 的支持人员之一“Caio”那里得到的答案是

      嗨,这就是它目前的工作方式,是的。我正在将您的反馈发送给我们的运行时团队,看看我们是否可以打包带有原始日期的文件。

      【讨论】:

      • 另一种方法可能是让存储后端检查哈希而不是上次修改。 S3 有一个 etag 是文件的 md5,但我认为没有记录。
      【解决方案4】:

      正如 Alen 所证实的,Heroku 在部署时会更改文件的修改日期。但是,Amazon S3 还有一个名为 etag 的属性,它是文件内容的 md5 哈希。可以使用它来检查文件是否已更改而不是修改日期,如 this Django snippet 中所实现的那样。

      我获取了该代码,将其打包并修复了我发现的一些错误,并将其作为 django-s3-collectstatic 放在 Github 上。它包括一个新的管理命令fasts3collectstatic,它只上传新文件。查看 Github 页面以获取安装说明。

      【讨论】:

        【解决方案5】:

        为什么不在本地机器上运行 collectstatic?

        python manage.py collectstatic --noinput --settings=settings.[prod]
        

        【讨论】:

          【解决方案6】:

          我同意这很烦人 - 您可以做几件事。我覆盖了 collectstatic 命令并将其连接到我的生产设置中。以下是我使用的命令:

          ```

          from django.core.management.base import BaseCommand
          class Command(BaseCommand):
              args = '< none >'
              help = "disables collectstatic cmd in contrib"
              def handle(self, *args, **kwargs):
                  print 'collectstatic disabled'
          

          ```

          我把它保存在 mysite/disablecollectstatic/management/commands 然后在生产设置中:

          INSTALLED_APPS += ('mysite.disablecollectstatic',)
          

          或者,您可以使用 Heroku 在实际调用命令之前先进行空运行的事实。如果失败,它将不会运行它,这意味着您可能会制造错误(例如,可能通过删除设置中的静态根目录)但这种方法让我感到紧张:

          https://devcenter.heroku.com/articles/django-assets#detection

          【讨论】:

          猜你喜欢
          • 2015-01-02
          • 2021-05-03
          • 2018-09-19
          • 1970-01-01
          • 2017-05-30
          • 2015-07-17
          • 2013-01-12
          • 2013-10-31
          • 2014-03-14
          相关资源
          最近更新 更多