Map subdomains with virtual urls in apache or nginx? [duplicate] - django

I'm currently developing a site where the functionality needs to be split into separate subdomains, dashboard.example.com, admin.example.com, and facebook.example.com. I would like everything to be served through a single Django project because everything will be using the same core models. I'm using Nginx as a front-facing proxy server handling static files and passing all other requests to Apache.
The solution I thought of was to map each of these subdomains to the appropriate app through nginx:
server {
listen 80;
server_name dashboard.example.com;
...
location / {
proxy_pass http://127.0.0.1/dashboard/;
...
}
}
server {
listen 80;
server_name admin.example.com;
...
location / {
proxy_pass http://127.0.0.1/admin/;
...
}
}
...doing that for each subdomain, effectively mapping the subdomains to their respective app url namespaces. The problem I encountered was that Django was unaware of the mapping, so when it reversed a URL, it would prepend /dashboard/, etc. to it, creating URLs like dashboard.example.com/dashboard/dashboard/. I figure I could write a custom reverse function to strip out the unnecessary subdirectory, but that seems like a band-aid.
Is there a better way to accomplish what I need, or should I restructure the project?
Thanks for your help.

Django's Sites framework (https://docs.djangoproject.com/en/1.7/ref/contrib/sites/) should be sufficient for this, if not, take a look at django-subdomains (http://django-subdomains.readthedocs.org/en/latest/) as seems to have a means of resolving your reverse URLs (based off a quick Google search, I've never used it myself!)

Related

nginx/gunicorn + Django: subdomain configuration for third party application integration

I am building a regular django project - the difference is this:
I want the django website to only "work" on a specified subdomain - for example, http://www.foo.mydomain.com
I want to use an entirely different application to run on another specified subdomain - e.g. http://www.foobar.mydomain.com
How do I setup a django project, so that it only runs on a specific subdomain, and does not intercept requests to other subdomains - so other other applications can run on other subdomains on the same parent domain?
[[Note 1]]
The second application (running on the other subdomain is not a django app). In fact, it's mattermost, that I want to run on the other subdomain - so I can integrate mattermost into my website.
[[Note 2]]
I'm using nginx + gunicorn as the server
Use a separate server block for each domain. See this document.
server {
server_name www.foo.mydomain.com;
...
}
server {
server_name www.foobar.mydomain.com;
...
}
Where a server_name match cannot be found, nginx will use the default server. So define a catch-all server block to prevent nginx using one of the server blocks above.
server {
listen 80 default_server;
deny all;
}

Splitting Django project across subdomains

I'm currently developing a site where the functionality needs to be split into separate subdomains, dashboard.example.com, admin.example.com, and facebook.example.com. I would like everything to be served through a single Django project because everything will be using the same core models. I'm using Nginx as a front-facing proxy server handling static files and passing all other requests to Apache.
The solution I thought of was to map each of these subdomains to the appropriate app through nginx:
server {
listen 80;
server_name dashboard.example.com;
...
location / {
proxy_pass http://127.0.0.1/dashboard/;
...
}
}
server {
listen 80;
server_name admin.example.com;
...
location / {
proxy_pass http://127.0.0.1/admin/;
...
}
}
...doing that for each subdomain, effectively mapping the subdomains to their respective app url namespaces. The problem I encountered was that Django was unaware of the mapping, so when it reversed a URL, it would prepend /dashboard/, etc. to it, creating URLs like dashboard.example.com/dashboard/dashboard/. I figure I could write a custom reverse function to strip out the unnecessary subdirectory, but that seems like a band-aid.
Is there a better way to accomplish what I need, or should I restructure the project?
Thanks for your help.
Django's Sites framework (https://docs.djangoproject.com/en/1.7/ref/contrib/sites/) should be sufficient for this, if not, take a look at django-subdomains (http://django-subdomains.readthedocs.org/en/latest/) as seems to have a means of resolving your reverse URLs (based off a quick Google search, I've never used it myself!)

Multiple Django projects under the same URL

I have two separate Django projects running on a Amazon EC2, that have different databases and use different settings files.
To do this, I use Nginx, that for the project1 listens at port 80 (url www.domain.com) and for the project2 listens at port 81 (url www.domain.com:81).
Using my website at some places, I noticed that project2 was excessively slow, due to maybe some networks block requests to specific ports.
So, I just want to use both projects with port 80. Is it possible, maybe with a different URL after the ".com"?
Sure it's possible.
Take a look at Nginx 'Server Blocks' to accomplish this...
http://wiki.nginx.org/ServerBlockExample
The caveat is that I don't believe it's possible to create 'Server Blocks' and route based on "different URL after the ".com"?" To be technically correct, it would be the URL path after the .com.
However, if you have different 'server names' (http://nginx.org/en/docs/http/server_names.html) than you could set up different 'server blocks' to handler requests to different Django applications running on the same box.
Say for instance you have Application1 using domain 'foo.com' and Application2 using domain 'bar.com'. A typical setup would look like,
http {
index index.html;
server {
server_name foo.com;
access_log logs/application1.access.log main;
root /var/www/application1.com/htdocs;
}
server {
server_name bar.com;
access_log logs/application2.access.log main;
root /var/www/application2.com/htdocs;
}
}
Just make sure both foo.com and bar.com point to your server running the Django apps.
You could use subdomains too if you'd like... app1.foo.com, app2.foo.com... both are valid server_name values.

How to mediate Django-Tastypie URI with Nginx routing

Specifically, I think I need Nginx to not consume (capture?) a piece of the URI I'm using to route a location. But I don't know if such a thing is possible.
Let me back up. I'm transitioning my app's setup. Before, I had an Nginx config file with a single location block matching everything:
server {
listen 80;
server_name ec2-54-234-175-21.compute-1.amazonaws.com;
location / {
...
proxy_pass http://localhost:8000/;
}
With this setup, up until now, I've just been running a Django app. After Nginx routes the user to the only endpoint, Django consumes the whole URI. What this means is that internally, Django chops off /api/ and then just has 1.0, which it also needs.
Now, I'm going to use Nginx to proxy for multiple servers, each hosting an app. Because of the aforementioned internal routing, the Django app needs to receive (at least) a URI of /1.0, while the other (on Flask) needs to get /api/2.0. However, in order for the Nginx location directives to make any sense, I have to differentiate the two applications. What I've worked out is that I'll just have the following two location directives:
server {
listen 80;
server_name ec2-54-234-175-21.compute-1.amazonaws.com;
location /api/[1.0] {
...
proxy_pass http://localhost:8000/;
}
location / {
...
proxy_pass http://localhost:8080/;
}
However, note the [1.0] in brackets. If that is there, what I've realized is that in order to actually access the intended resource, I have to enter a URI of /api/1.0/1.0. So, somehow I need a non-consuming location in my nginx conf. If I knew how to express this in simpler terms, I would. Is what I want possible?
About a week after asking this question, a coworker pointed out the answer I wanted, and it's very simple. The key is in the malleability that Nginx gives you with its routing. Because I wanted to access a resource that was at /api/1.0, but still needed to differentiate the two apps in my config, I do the following:
server {
listen 80;
server_name ec2-54-234-175-21.compute-1.amazonaws.com;
location /api/1.0 {
...
proxy_pass http://localhost:8000/api/1.0;
}
location /api/2.0 {
...
proxy_pass http://localhost:8080/api/2.0;
}
This effectively makes the URL "non-consuming", as I wrote above, because I use the desired resource URL to route with, and then duplicate it in referencing the actual location within the specific app.
Maybe this will help someone else.

redirect clients connecting via "www.domain.com" to "domain.com" using django

it seems like google links to my page contain a "www." before the domain, this causes security errors since I'm reading data from the canvas and the images will be marked as cross-orign if they are from "www.x.com" rather than "x.com".
So i'm wondering what's the nicest way to redirect people from the url with the www. in it to one without?
(alternately, can I get google to link without the www?)
Thanks
The best way would be to let your webserver (apache/nginx) handle the redirect, instead of doing it in Django.
In nginx it could look something like this:
server {
listen 80;
server_name www.example.com;
rewrite ^(.*) http://example.com:80$1 permanent;
}
Of course you could do it in Django, simply check for the existence of the subdomain www and then redirect to the same URL without this subdomain. In this case you would need to add this logic to all of your views though (could be a decorator for example). Still, its hard to maintain and the better and simpler approach is the one I mentioned above.