我与 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 中受益。