Basically I\'m structuring my app similar to this GitHub project: https://github.com/zackargyle/angularjs-django-rest-framework-seed
Is it possible to deploy both the ba
I'm in the exact same boat with AngularJS as my client and django-rest-framework as my service. I also have the same type of git setup where the server and client code are siblings in the same repository. I don't have any experience with Heroku and I'm new to beanstalk but I was able to deploy my site and it's working on AWS beanstalk.
With beanstalk there are two ways I know of to deploy your code.
I automated the zip creation using a python script. Amazon's walkthrough provides an example python zip. You have to structure it properly, mine looks roughly like this
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
I know you didn't specifically ask but the .config file inside .ebextensions/ took me way too long to get working. It can be formatted as YAML or JSON (can be confusing at first as every blog shows it differently). This blog helped me out quite a bit just be careful to use container_commands: and not commands:. I lost a few hours to that...
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": ""
"AWS_ACCESS_KEY_ID": ""
"AWS_S3_Bucket": ""
In the zip you create (if you follow the beanstalk guides on django) the client code in your /static/ folder is automatically pushed to s3 when you deploy.
This setup isn't perfect and I plan on fine tuning things but it's working. Here are some downsides I ran into that I haven't solved yet:
UPDATE 4-17-2014
I further refined this setup so I no longer have to go to mysite.com/static/ to load my index.html. To do so I used a django class based view to map index.html to the root of my site. My urls.py looks like
urlpatterns = patterns('',
(r'^$', TemplateView.as_view(template_name="index.html")),
...
)
and in my settings.py I configured TEMPLATE_DIRS as follows
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__) , '../static').replace('\\','/')
)
I use ../static because my static directory is a sibling of my app directory.
The last piece was to update my Gruntfile.js so 'grunt build' prefixes all the relative URLs in my angular code with the static folder. I used grunt-text-replace for this. It's the last task that runs after my code is sitting minified in a /dist folder. The downside to this approach is I'll have to update this task if I ever add static content to a new subfolder besides scripts, bower_components, styles, etc.
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'
}
]
}
},
Now django will serve my index.html page but everything else in my /static/ directory can benefit from a CDN.