Nginx and Django on Dotcloud - django

I currently have a dotcloud app that uses django to serve everything. It works great, however, we recently had our site redone in angular.js, and I don't want to use django to serve the actual html pages (I want to just use nginx for that), but I want django to serve some links for the API we built for the angular code to use.
Is it possible for me, in the same app, to configure nginx to serve some static files for particular urls, and have it send other urls for django to serve?
I want nginx to serve my index.html page is a request comes in to wwww.example.com, but if a request for example.com/api/login/ comes in, I want that to be handled by django. Is this possible?

Yes, you can do what you are looking for, you just need to add an nginx.conf to your project and then specify which urls you want nginx to serve and which ones you want django to serve, by default they will all go to django, so you just need to specify which ones you want to be served by nginx.
Here is a link to the documentation: http://docs.dotcloud.com/0.4/guides/nginx/
Link to the nginx documentation on location blocks: http://wiki.nginx.org/HttpCoreModule#location
Here is an example for serving static files from nginx, you can use this as a guide to do what you need.
location /media/ {
root /home/dotcloud/data ;
}
location /static/ {
root /home/dotcloud/volatile ;
}

Related

Make django handle subdomain suffix

We're hosting several dockerized web-apps on our webserver, let's call it group.example.com. Our subdomains are handled via nginx as suffixes though, which translates to something like group.example.com/app1/ group.example.com/app2/ as root urls.
When using Django, we run into problems though, as all its urls generated by url in the templates such as home will be relative links, so rendered to home. This relative link will not be interpreted correctly, leading to the main, non-app page group.example.com.
So the goal is to have an app based prefix such as /app1/ for all links. I can hardcode these for static links, but there has to be a more elegant way. Also this leads to problem for the used forms submitting to the wrong page - redirecting again back to the main, non-app page group.example.com.
I tried adding /app1/ to all registered urls as prefix, but that doesn't seem to work either - that way the app is running but user would need to visit group.example.com/app1/app1/ to get to the index, and the relative links still don't work correctly.
In the app docker-container we're running the web-app with nginx and uwsgi. It works fine when using correct subdomains such as app1.example2.com - but we don't have that capability on our new faster webserver we want to host the app on.
Is there a way to resolve this using the app containers nginx, uwsgi or django / middleware config to get the links to resolve to group.example.com/app1/ as root?
As far as I know, there is two ways to resolve it.
One use SCRIPT_NAME in the NGINX configuration. For example, based on this server fault answer:
location /app1/ {
SCRIPT_NAME /app1;
# rest of the config
}
Two You can add FORCE_SCRIPT_NAME in your settings.py:
FORCE_SCRIPT_NAME = '/app1'
FYI, I would prefer using first solution.

Django: How can I serve an angular app without using STATIC_URL during development?

I have a django project which is making use of django-rest-framework to provide an api for an angular client.
The entire angular app is developed separately to the django project, and doesn't make use of any django templates or suchlike.
Eventually the angular app will be served as a static asset via nginx or something along those lines.
However, during development, I would like the django development server to serve the angular app.
The issue I have is that none of the static assets in index.html are prefixed with STATIC_URL or a similar static prefix which django can look for.
Attempting to serve all non-api routes as static files as such:
urlpatterns += static(r'', document_root=settings.ANGULAR_APP_ROOT)
gives an exception
Empty static prefix not permitted
I know that in nodejs express server you can use something like:
app.use(express.static(path.join(config.root, 'app')));
which works seamlessly. I guess it searches for any paths in the configured folder and if any match the requested url, serves them.
I do not want to force django specific code/prefixes into the angular app (ala STATIC_URL etc)
What I'm looking for is some middleware which will offer a fallback route for anything unmatched by the existing urlpatterns and search a filesystem path for a matching asset and serve it if found.
Is it possible to get the static assets served like this with the django development server?

Webfaction: How do I run a Static/Perl app and Django app under the same website

I have an existing Perl app that I'm moving to a Webfaction website. I will be adding Django apps to this Webfaction website too.
I would like the Django app to get first call and so would want its URL path to be /
This would allow me to add any new URLs to the urls.py I wish as my app grows.
If the URL doesn't match anything in the urls.py I would like it to get passed to the static Perl app.
For example
/app1 -> Django
/app2 -> Django
Everything else not picked up by urls.py I would want going to my Perl app
For example:
/index.html -> Static/Perl app
/about.html -> Static/Perl app
/contact.html -> Static/Perl app
/apps/perlapp1.cgi -> Static/Perl app
etc
How do I go about achieving this in Webfaction?
The largest benefit of using a static app for the static pages (and not rendering them using simple views/templates using django) is the performance gain by not involving django at all in this request. but if you let django run and look through all the urls for a match, and only render static if there's not match, you're not getting that benefit.
I use /static/ as a location for the static app and / for django. so every request starting with /static/ skips the django server. whenever I want to link to static content I just add /static/ to it.
Well, Webfaction makes this very easy! In your control panel, go to "websites", edit (or create) the website, and in the process there add any number of new (or existing) apps. You can map those apps any way you like. But note that for the first app you will be adding you won't have a choice (it will be mapped to "/"), but for additional apps you can specify your own path.
Create or edit a website:
Add the first application:
Add additional applications (note: now there is a URL option):
The result:
Hit Save and you're done.

Django and Serving Static Files

I'm hosting a site on WebFaction using Django/mod_python/Python2.5. I've recently run into the concept of static files (when setting up my Django admin).
From what I understand, serving static files is simply the idea of telling the server to serve files directly from a specific directory, rather than first routing the request through apache, then mod_python, then django, and finally back to the user. In the case of WebFaction this helps especially since there are two Apache servers that your request must go through (your app's server and the main public server).
Why is it that when I setup Django's static files, it only needs the /media folder in /contrib/admin? Is it just that all of Django's static content is related to the admin panel?
When I want to serve my own static content (images, css, etc.) should I include it in the same /media folder or set up another alias for my own content (/my_media)?
Yes, the static files used by Django are pretty much related to images, javascript and css for the admin. All other static content comes from your application. You can keep both sets (yours and the admin) under the same server. Just set the appropriate folders in the settings file.
http://docs.djangoproject.com/en/dev/ref/settings/#admin-media-prefix
http://docs.djangoproject.com/en/dev/ref/settings/#media-root
http://docs.djangoproject.com/en/dev/ref/settings/#media-url
See this post for a little more information:
Django and Static Files
Django's static files (e.g. js, css, images, etc.) are all in the media folder, and are related to the admin panel.
On WebFaction to save processing power, and more importantly memory, it is better to serve these from your secondary apache server (or even better from nginx or lighttpd) without having to go through mod_python and Django.
I use the following folder setup for my files:
media
css
js
img
etc
admin
css
js
img
See http://forum.webfaction.com/viewtopic.php?id=1981 for how to setup nginx as your secondary server on WebFaction if you are interested.

How do you serve vanilla/custom pages in an MVC based site?

Let's say you've setup your site using Pylons, Django and most of the site runs fine and according to the framework used. However, what if you had a custom section that was entirely say, composed of flat html files and its own set of images, which you didn't have time to actually incorporate using the framework and were forced to basically support, under the same domain? Should there be some sort of default controller/view that's super bare minimalistic or do frameworks such as these somehow offer support in some smart way?
I realize also that potentially one could setup a new subdomain and reroute it to an entirely different directory, but I'm just curious as to how one would solve this when forced to deal with a framework.
When serving static pages I'd rather avoid having Django or Pylons handle the request, and handle it with the web server only. Using Nginx, you'd use a directive like:
location / {
root /whatever/the/path/is/;
# if the file exists, return it immediately
if (-f $request_filename) {
break;
}
# pass requests to MVC framework
# i.e. proxy to another server on localhost:
proxy_pass http://127.0.0.1:80;
}
For pylons you should be able to drop your static html files in the public directory. If there isn't a controller for a url then I think pylons looks in the public folder next.
For Django, I would serve these in exactly the same way as you serve your static assets - in your site_media directory, along with subdirs for js, css and img, you could have an html directory. Then the URL would just be /site_media/html/whatever.html.
In Django take a look at flatpages. It's part of the django.contrib package and uses flatpages middleware to serve up flat HTML controlled through the admin interface. For basic purposes, serving up additional about pages or the like this should do the trick.
You could also just create an HTML folder and - using mod_python, at least - set no handler for that path in the Apache configuration file (e.g. vhost.conf).