Multiple Django projects under the same URL - django

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.

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;
}

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

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!)

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!)

ssl with django on AWS

I have SSL certification at the ELB level for my site hosted on Amazon. I used the following site to setup a middle ware to forward all http requests to https:
http://djangosnippets.org/snippets/2472/
It's working great. But here's my question. EACH request is getting forwarded, so I notice a slight lag when clicking links, etc. Nothing extreme. But is there a way to force django to do everything via https? When I have code to HttpResponse and HttpResponseRedirect, how can I have it default to https instead of http? I tried to search for this and was unsuccessful...
I know it's possible if I type https://www... for each URL for redirect and on the links for the pages, but I wanted to avoid doing it that way if possible.
Looking at the middleware you posted, it is doing exactly what you mentioned you did not want to manually do i.e append https to every incoming http request from your domain. I would recommend you offload this job to the front-end server (Either nginx or apache) .
Example with
Nginx
Apache
When Django builds absolute URIs to redirect to, it checks request.is_secure to decide what protocol scheme it should be using (http, https, or ftp).
Django defaults to doing this based on the protocol used for the request, but as you've identified, when behind an LB or proxy this can be wrong due to SSL termination at the LB/proxy level.
You can configure Django to detect this exact scenario using the SECURE_PROXY_SSL_HEADER setting.
We use Nginx currently to load balance, force SSL on requests, and terminate SSL connections as they are proxied to internal app servers. It doesn't have as fancy load balancing capabilities, but Nginx is small and fast enough to put anywhere.
Here's the code bits you may need:
# listen on port 80 and redirect to SSL.
server {
listen 80;
server_name site.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
# listen on port 443, terminate SSL, and proxy to internal web app
# can be node, rails, whatever.
server {
listen 443;
server_name site.com;
gzip on;
client_max_body_size 250M;
ssl on;
ssl_certificate /etc/nginx/site.com.crt;
ssl_certificate_key /etc/nginx/site.com.key;
keepalive_timeout 70;
location / {
proxy_pass http://127.0.0.1:8080;
# We add this extra header just so proxied web app
# knows this used to be an SSL connection.
proxy_set_header x-https 1;
include /etc/nginx/conf.d/proxy.conf;
}
}

Django- session cookies and sites on multiple ports

I have multiple Django projects running on one server using gunicorn and nginx. Currently they are each configured to run on a unique port of the same IP address using the server directive in nginx. All this works fine.
...
server {
listen 81;
server_name my.ip.x.x;
... #static hosting and reverse proxy to site1
}
server {
listen 84;
server_name my.ip.x.x;
... #static hosting and reverse proxy to site2
}
...
I came across a problem when I had 2 different projects open in 2 tabs and I realized that I could not be logged into both sites at once (both use the built-in Django User model and auth). Upon inspecting the cookies saved in my browser, I realized that the cookie is bound to just the domain name (in my case just an ip address) and it does not include the port.
On the second site, I tried changing SESSION_COOKIE_NAME annd SESSION_COOKIE_DOMAIN, but it doesn't seem to be working and with these current settings I can't even log in.
SESSION_COOKIE_DOMAIN = 'my.ip.x.x:84' #solution is to leave this as default
SESSION_COOKIE_NAME = 'site2' #just using this works
SESSION_COOKIE_PATH = '/' #solution is to leave this as default
#site1 is using all default values for these
What do I need to do to get cookies for both sites working independently?
Just change the SESSION_COOKIE_NAME. The SESSION_COOKIE_DOMAIN doesn't support port numbers afaik. So they are all the same for your apps.
Another solution that doesn't require hard-coding different cookie names for each site is to write a middleware that changes the cookie name based on the port the request came in on.
Here's a simple version (just a few lines of code).