Cloud Foundry 上的 Django 项目未加载管理界面 CSS

Django project on Cloud Foundry not loading admin interface CSS

我有一个使用 Cloud Foundry 部署的简单 Django 项目。在本地 运行ning 时,管理界面(我的简单项目使用的唯一界面)看起来不错。但是,在部署时,CSS 明显损坏。 CSS 和 JS 资产的 URL return 404.

Other answers 类似的问题说解决方法是collectstatic命令。为了 运行 在 Cloud Foundry 的上下文中,我输入以下内容(显然是真实的应用程序名称和路径):

cf run-task app-name -c "python app-path/manage.py collectstatic"

由此记录的输出看起来很有希望:

128 static files copied to '/home/...path.../settings/static'.

然而,尽管有这个明显的承诺,CSS 还是坏了。

仅供参考,我的设置包括:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

STATIC_URL = '/static/'

PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')

cf run-task app-name -c "python app-path/manage.py collectstatic"

这不会按照您想要的方式工作。当您 cf run-task 系统正在启动一个新容器并 运行 在该新容器中执行您的命令。该命令将执行 运行 并执行它应该执行的操作,但是当任务结束时,它将全部丢弃。

我不熟悉 DJango,所以我不知道该命令在做什么,也不知道它有什么细微差别,但在 CloudFoundry 的上下文中,您可能有两个选择。

第一个,运行 python app-path/manage.py collectstatic 在你之前cf push。如果是某种构建过程,可能足以将文件放在需要的地方。

第二个,运行 应用程序启动前的命令。有两种方法可以做到这一点:

  1. 运行 cf push -c 'python app-path/manage.py collectstatic && python <your-normal-start-script.py>,将 <your-normal-start-script.py> 替换为您通常使用的 运行。这将首先执行 collectstatic 命令,如果它通过,然后 运行 您通常的启动命令。您也可以在 manifest.yml.

    中设置 command:
  2. .profile script 添加到应用程序的根目录。在脚本中,添加命令 python app-path/manage.py collectstatic。该脚本将在您的应用程序启动之前由平台执行。

在这些选项中,我推荐选项 #2,即 .profile 脚本,因为它可以与 Python buildpack 为 运行 您的应用程序生成的任何命令一起使用.因此,它对您来说工作更少。

回答我自己的问题:我试图做的根本行不通。 Django 的 runserver 命令 only serves static files 如果 DEBUG = True 在适当的设置文件中,或者如果使用 --insecure 开关。这两者都被认为不适合部署使用。

虽然 staticfiles documentation 声称该应用程序组织静态文件“可以很容易地在生产中提供”,但实际上并不那么容易。理想情况下,文档应该阐明 collectstatic 仅当 Web 服务器配置为期望文件并从命令放置它们的任何地方提供它们时才使文件可用。

根据我的理解,这是我可能的前进道路:

  1. 使用网络服务器,如 nginx、Gunicorn 或 Apache
  2. 从 AWS S3 等云提供商提供静态资产
  3. 简单地 运行 collectstatic --insecure 这显然被认为是不安全的