【问题标题】:Client side JS (e.g. AngularJS) + Django REST Backend: Deploy onto single PaaS?客户端 JS(例如 AngularJS)+ Django REST 后端:部署到单个 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 但它缺乏更具体的细节。

【问题讨论】:

    标签: django angularjs heroku amazon-web-services amazon-elastic-beanstalk


    【解决方案1】:

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

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

    1. 使用 here 描述的 eb 和 git。
      • 如果您想直接推送源代码,效果很好。
    2. 创建您自己的 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 中受益。

    【讨论】:

      猜你喜欢
      • 2013-10-10
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 2015-04-23
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      相关资源
      最近更新 更多