How can I serve a Django application using the SPDY protocol? - django

What is the best way to serve a Django application over the SPDY [1] protocol?
[1] http://www.chromium.org/spdy

One way is to run Django on Jython with Jetty - http://www.evonove.it/blog/en/2012/12/28/django-jetty-spdy-blazing-fast/
Also, apparently nginx has some draft module for SPDY

It works with nginx > 1.5.10 and Django run as fastcgi server.
Recent versions of Chrome and Firefox dropped support for SPDY v2. So you need at least SPDY3 support on the server side. Nginx versions higher than 1.5.10 support version 3 of the protocol.
Django Mainline Installation
Currently (as of Feb 2014) Nginx > 1.5.10 is only available from the mainline branch, not from stable. On most Linux distributions, it is easiest to install mainline packages provided by the nginx project.
Nginx and Django configuration
The Django documentation explains how to run Django with Nginx through fastcgi. The configuration that is provided there can be used as a starting point.
In addition, you need SSL certificates for your host and extend the Nginx configuration in the following ways:
The listen configuration options needs to be modified to:
from listen 80; to listen 443 ssl spdy;.
You need to add basic ssl configuration options, most importantly a certificate and key.
So, both modifications combined, the configuration may look as follows:
server {
listen 443 ssl spdy;
server_name yourhost.example.com;
ssl_certificate <yourhostscertificate>.pem;
ssl_certificate_key <yourhostskey>.key;
ssl_prefer_server_ciphers on;
location / {
include fastcgi_params;
fastcgi_pass 127.0.0.1:8080;
}
}
Then run your Django as in fastcgi mode, as follows:
python ./manage.py runfcgi host=127.0.0.1 port=8080
Testing your setup
Point your browser to https://yourhost.example.com
You should be able to verify that the connection is done via SPDY in:
Chrome: Look for an active SPDY session in chrome://net-internals/#spdy
Firefox: Check the Firebug Network tab and look for the X-Firefox-Spdy:"3.1" response header.

Related

How to hoste multiple Django websites on single sever using NGINX and uWSGI

i have a linux server running under Ubuntu server 20.04 LTS, i'm using NGINX as a web server and uWSGI as an application server, i have a Django website is already installed and running perfectly, and the exact way i did that is by following the instructions from this video https://www.youtube.com/watch?v=ZpR1W-NWnp4&t=2s, but the thing is that i have several websites that needs to be installed, so i tried to redo all of it for a second website on the same server, but that did not work at all.
My question is: once i install a Django project exactly the way shown in the video using Nginx and uWSGI, how to install another Django project in a practical manner, in other words how to install multiple Django projects using Nginx and uWSGI.
this is my nginx server block saved at /etc/nginx/sites-available/project_name.conf
# the upstream component nginx needs to connect to
upstream django {
server unix:///home/user/project_name/project_name.sock;
}
# configuration of the server
server {
listen 80;
server_name domain.com www.domain.com;
charset utf-8;
# max upload size
client_max_body_size 75M;
# Django media and static files
location /media {
alias /home/user/project_name/media;
}
location /static {
alias /home/user/project_name/static;
}
# Send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/user/project_name/uwsgi_params;
}
}
Try out this bash script I wrote. It set ups as many Django websites as you want with a simple command. The script installs all the dependencies on your server, creates a virtual environment for each site, and configures a database server and Gunicorn connector.

How to server HTTP/2 Protocol with django

I am planing to deploy my Django application with HTTP/2 protocol but I'm unable to find the proper solution. How can I serve my Django web application with HTTP/2, the only thing that I find is hyper-h2.
I read the documentation but unable to setup the connections.
You can do with Nginx proxy
if you have existing nginx config. you do by just adding a word .http2 in listen
listen 443 ssl http2 default_server;
full document avaliable in
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-16-04
One option is to use Apache httpd server with mod_wsgi. Apache supports terminating HTTP/2. The link to your Django application is still via WSGI API so you don't really get any access to HTTP/2 specific features in your application. You can though configure Apache to do things like server push on your behalf.
https://httpd.apache.org/docs/2.4/howto/http2.html
https://httpd.apache.org/docs/2.4/mod/mod_http2.html
To support HTTP 2.0, You can deploy Django apps on web servers like Daphne using ASGI (which is the spiritual successor to WSGI).
you can read more about deploying Django with ASGI in the official documentaion
to read more about ASGI and what is it, introduction to ASGI
to read more about Daphne server, official repository

How do you serve ember-cli from https://localhost:4200 in development

For our authentication to work with our ember app we need to serve the app from a secure url. We have a self signed ssl cert.
How do I setup the ember-cli to serve the index.html form a https domain.
Cheers
Also see https://stackoverflow.com/a/30574934/1392763.
If you will always use SSL you can set "ssl": true in the .ember-cli file for your project which will result in the ember serve command using SSL by default without having to pass the command line flag every time.
By default ember-cli will look in an ssl folder in the root of your project for server.key and server.crt files but you can customize that as well with the --ssl-key and --ssl-cert options to provide an alternate path.
If you don't already have a self signed SSL certificate for development you can follow these instructions to easily generate one: https://devcenter.heroku.com/articles/ssl-certificate-self
Example .ember-cli:
{
"disableAnalytics": false,
// Use SSL for development server by default
"ssl": true,
"ssl-key": "path/to/server.key",
"ssl-cert": "path/to/server.crt"
}
EDIT
For googlers, this is no longer true. Use ember-cli --ssl
Thx to xdumaine Jul 12 at 10:08***
emphasized textYou can't directly from ember-cli without putting your hand in the code which I don't recommend :)
If you want to go this way look at: node_modules/ember-cli/lib/tasks/server/express-server.js and may be also into node_modules/ember-cli/lib/tasks/server/livereload-server.js
For those who still want to go through a web server :
However there are other cleaner solutions, for example use nginx as a (reverse) proxy :) or ever serving directly from nginx on the /dist folder :)
Reverse basic example with nginx (didn't tried with ssl but should theoretically work :p) :
server {
listen 443;
server_name *.example.com;
ssl on;
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/key.key;
location / {
proxy_pass http://localhost:4200;
}
}
I said nginx but actually any webserver can do the trick right :)
NaB DO NOT USE ember serve IN PRODUCTION
I use the tunnels gem with pow port-proxying.
Update: more detail
Using a real web server (like the previous answer with nginx) is a great way to go, and is probably more like your production setup. However, I manage a lot of different projects, and am not that interested in managing an nginx configuration file for all of my projects. Pow makes it easy to make a lot of different projects available on port 80 on one development machine.
Pow has two main modes. The primary function is to be a simple server for Rack applications, accessed via a custom local domain such as http://my-application.dev/. This is done by symlinking ~/.pow/my-application to a directory that contains a rack application. However, pow can also proxy requests to a custom local domain to a specified port by creating a file that contains only the port number (such as echo 4200 > ~/.pow/my-application). This makes it easy to develop locally with an actual domain (also, as a side note, subdomains work too, which is really handy; for example, foobar.my-application.dev will also route to my-application).
Tunnels makes it easy to use pow with https.
Setup
# Install pow
curl get.pow.cx | sh
# Set up pow proxy for your ember app
echo 4200 > ~/.pow/my-application
# Start your ember server
ember serve # specify a port here if you used something else for pow proxy
# Check that http://my-application.dev correctly shows your ember app in the browser
# Install tunnels
gem install tunnels # possibly with sudo depending on your ruby setup
# Start tunnels
sudo tunnels
# Now https://my-application.dev should work

uwsgi/nginx/django client certificate authentication elevation at runtime

Preamble
I have a django application set up to run under uwsgi proxy passed by nginx. In Iceland we have a smart card client certificate system in place, embedded in debet cards, distributed free by the debet card issuers, i.e. banks. I am attempting to support this environment for authentication, while retaining the ability to issue logic when authenticating, making the process interactive for the user. Currently we use Apache/mod_wsgi to host the application and use a location directive /auth/smartcard where we require client certificate handshakes. The root of the site is just plain https. This relegates the process to the server only, denying us the ability to interact with the user in a constructive manner.
The configuration so far
uWSGI ini:
[uwsgi]
chdir=/home/vagrant/gimli/src
socket=localhost:5000
processes=1
module=application_name.wsgi:application
env DJANGO_SETTINGS_MODULE=application_name.settings
max-requests=5000
home=/home/vagrant/virtualenvs/gimli
py-autoreload=True
nginx settings
server {
<snip>
ssl on;
ssl_protocols SSLv3 TLSv1;
ssl_certificate ssl/host.domain.is.crt;
ssl_certificate_key ssl/host.domain.is.key;
ssl_client_certificate ssl/ca_chain.crt;
ssl_verify_client optional;
ssl_verify_depth 2;
error_log /var/log/nginx/host.domain.error.log debug; # debug for debugging ssl
access_log /var/log/nginx/host.domain.is.access.log;
location / {
include uwsgi_params;
# Client cert support
uwsgi_param SSL_CLIENT_ID $ssl_client_s_dn;
# Bind parameters
uwsgi_pass localhost:5000;
}
</snip>
} # /server
These configurations enable SSL and optional client certificates if supplied to the browser by the smartcard reader (usb dongle). Therefore the ssl_verify_client optional directive. We are not married to Nginx, though we would prefer not to run uwsgi naked.
The question
Is it possible - at runtime - to issue a directive back from the application to the server to elevate the ssl connection to require a client certificate, using either uwsgi or nginx? Is it possible, essentially, to alter the state of the ssl_verify_client setting, renegotiating the ssl handshake?

Configuration for Django, Apache and Nginx

I've setup my Django application on Apache+mod_wsgi. To serve the static files I'm using Nginx, as suggested on Django's project website. http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
Apache is running on port 8081 and nginx is on port 80. Now some people have suggested that my configuration is wrong and I should reverse the roles of Apache and Nginx. I'm not sure why that should be. And if indeed my configuration is wrong, why would django website suggest the wrong method?
The django docs you linked to do not suggest you use apache as a reverse proxy. They simply suggest you use a separate web server, so I'd say the docs are not clear on that subject -- they are not suggesting anything wrong.
My initial answer was assuming you had nginx as a reverse proxy because port 80 is the HTTP port, the one used when a browser attempts to go to a url with no port specified.
There are numerous complete guides to setting up nginx + apache via a quick google search but here is the gist for setting up nginx:
location / {
# proxy / requests to apache running django on port 8081
proxy_pass http://127.0.0.1:8081/;
proxy_redirect off;
}
location /media/ {
# serve static media directly from nginx
root /srv/anuva_project/www/;
expires 30d;
break;
}
All you need to do is remove the proxy lines from your apache configuration and add the proxy statements to your nginx.conf instead.
If you really want to serve your site from port 8081, you could potentially have nginx listen on port 8081 and have apache listen on a different port.
The point is, apache sits in some obscure port, only serving requests sent to it from nginx, while static file serving is handled by nginx.