客户端 JS(例如 AngularJS)+ Django REST 后端:部署到单个 PaaS?

Posted

技术标签:

【中文标题】客户端 JS(例如 AngularJS)+ Django REST 后端:部署到单个 PaaS?【英文标题】:Client side JS (e.g. AngularJS) + Django REST Backend: Deploy onto single PaaS? 【发布时间】:2014-03-14 16:33:02 【问题描述】:

基本上,我正在构建类似于此 GitHub 项目的应用程序: https://github.com/zackargyle/angularjs-django-rest-framework-seed

是否可以将后端和前端都部署到单个 PaaS(例如 Heroku/Elastic Beanstalk)上?

拥有一个分离的 REST 后端和 javascript 前端似乎是一种更清洁/更可扩展的方式来做事,而不是像 [django-angular]: (http://django-angular.readthedocs.org/en/latest/index.html/) 那样尝试将它们混合在一起,或者将 REST 后端与像http://blog.mourafiq.com/post/55099429431/end-to-end-web-app-with-django-rest-framework这样的Django应用程序

如果无法将其轻松部署到 Elastic Beanstalk 上,是否有一种简单的方法可以将 Django 后端部署到 Elastic Beanstalk 上,并将 AngularJS 前端部署到 Amazon EC2/S3 上,只需最少的配置?

我知道在此之前有类似的讨论:Client JS + Django Rest Framework 但它缺乏更具体的细节。

【问题讨论】:

【参考方案1】:

我与 AngularJS 作为我的客户和 django-rest-framework 作为我的服务完全一样。我也有相同类型的 git 设置,其中服务器和客户端代码是同一个存储库中的兄弟姐妹。我对 Heroku 没有任何经验,而且我是 beanstalk 新手,但我能够部署我的网站,并且它正在 AWS beanstalk 上运行。

使用 beanstalk,我知道有两种部署代码的方法。

    使用 here 描述的 eb 和 git。 如果您想直接推送源代码,效果很好。 创建您自己的 zip 以通过 AWS 管理控制台上传到 beanstalk。亚马逊有一个演练here。 我选择的路线是为了在部署之前“咕噜构建”我的客户端并使用服务器代码压缩。

我使用 python 脚本自动创建了 zip。 Amazon's walkthrough 提供了一个示例 python zip。你必须正确地构造它,我的看起来大致是这样的

app.zip
  /.ebextensions/
  /.elasticbeanstalk/
  /app/     <-- my django-rest-framework project (settings.py, wsgi.py, etc.)
  /restapi/ <-- my django-rest-framework application (my api)
  /static/  <-- AngularJS results of 'grunt build' put here
  /manage.py
  /requirements.txt

我知道你没有特别问,但是 .ebextensions/ 中的 .config 文件让我花了太长时间才开始工作。它可以被格式化为 YAML 或 JSON(起初可能会令人困惑,因为每个博客都以不同的方式显示它)。这个blog 帮助了我很多,只是要小心使用 container_commands: 而不是 commands:。我为此浪费了几个小时......

container_commands:
 01_syncdb:
  command: "django-admin.py syncdb --noinput"
  leader_only: true
option_settings:
 "aws:elasticbeanstalk:container:python:environment":
  "DJANGO_SETTINGS_MODULE": "app.settings"
 "aws:elasticbeanstalk:container:python":
  "WSGIPath": "app/wsgi.py"
  "StaticFiles": "/static/=static/"
 "aws:elasticbeanstalk:container:python:staticfiles":
  "/static/": "static/"
 "aws:elasticbeanstalk:application:environment":
  "AWS_SECRET_KEY": "<put your secret key here if you want to reference from env variable>"
  "AWS_ACCESS_KEY_ID": "<put your access key here>"
  "AWS_S3_Bucket": "<put your bucket here>"

在您创建的 zip 中(如果您遵循 beanstalk guides on django),您的 /static/ 文件夹中的客户端代码会在您部署时自动推送到 s3。

此设置并不完美,我计划进行微调,但它正在工作。以下是我遇到的一些尚未解决的缺点:

由于我将客户端代码放在 static/ 文件夹中,因此我的站点位于 mysite.com/static/ 下。理想情况下,我希望它作为 mysite.com 的根,而我的 django-rest-framework 内容位于 mysite.com/api/ 下 默认情况下,如果您在 beanstalk 上使用 self describing api,则不会推送资产,因为它们位于您的 python 目录中,而不是您的源代码。

2014 年 4 月 17 日更新

我进一步完善了此设置,因此我不再需要访问 mysite.com/static/ 来加载我的 index.html。为此,我使用django class based view 将 index.html 映射到我网站的根目录。我的 urls.py 看起来像

urlpatterns = patterns('',
  (r'^$', TemplateView.as_view(template_name="index.html")),
  ...
)

在我的 settings.py 中,我将 TEMPLATE_DIRS 配置如下

TEMPLATE_DIRS = (
  os.path.join(os.path.dirname(__file__) , '../static').replace('\\','/')
)

我使用 ../static 是因为我的静态目录是我的 app 目录的兄弟。

最后一点是更新我的 Gruntfile.js,所以“grunt build”在我的 Angular 代码中的所有相对 URL 前加上静态文件夹。我为此使用了grunt-text-replace。这是我的代码在 /dist 文件夹中缩小后运行的最后一个任务。这种方法的缺点是,如果我将静态内容添加到脚本、bower_components、样式等之外的新子文件夹中,我将不得不更新此任务。

replace: 
    replace_js_templates: 
        src: ['dist/scripts/*.js'],
        overwrite: true,                 // overwrite matched source files
        replacements: [
            from: /templateUrl:\s*"/g,
            to: 'templateUrl:"static/'
        ]
    ,
    replace_index: 
        src: ['dist/index.html'],
        overwrite: true,                 // overwrite matched source files
        replacements: [
            from: /(src|href)="(bower_components|styles|scripts)/g,
            to: '$1="static/$2'
        
        ]
    
,

现在 django 将为我的 index.html 页面提供服务,但我 /static/ 目录中的所有其他内容都可以从 CDN 中受益。

【讨论】:

以上是关于客户端 JS(例如 AngularJS)+ Django REST 后端:部署到单个 PaaS?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS中的ExpressJS变量 - 平均堆栈

如何在 AngularJS 客户端和 Node.js 服务器之间重用代码 [关闭]

AngularJs + Strophe.js 接收消息

Hogan Js 和 AngularJs 与 Node Js

在backbone.js 和/或knockout.js 中的AngularJS 示例

Angularjs 学习笔记