Question

I would like to run several virtual hosts via nginx, each serving a different django app via fcgi. Is this possible? If so, does anyone have good resources on where/how to start? The nginx docs seem to be mostly examples, but none of the particular config I'm attempting...

Was it helpful?

Solution

There have been two pretty good blog posts lately about setting up nginx, but both are using nginx to serve static (or cached) content and apache + mod_wsgi to serve Django. I prefer this myself because mod_wsgi makes process management so much easier than fcgi (among other advantages).

Anyway, here are the posts:

EDIT: ok I dug out an old tar file with my nginx + django + virtual host config files from a year ago before I switched to apache + mod_wsgi. This was a development machine, so you'll want to adjust # of workers, connections, etc.

nginx.conf:

user nginx nginx;
worker_processes 2;

error_log /var/log/nginx/error_log info;

events {
    worker_connections  1024;
    use epoll;
}

http {
    include         /etc/nginx/mime.types;
default_type    application/octet-stream;

log_format main
            '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $bytes_sent '
            '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

client_header_timeout   3m;
client_body_timeout     3m;
send_timeout            3m;

connection_pool_size            256;
client_header_buffer_size       1k;
large_client_header_buffers     4 2k;
request_pool_size               4k;

gzip on;
gzip_min_length 1100;
gzip_buffers    4 32k;
gzip_types      text/plain text/html application/x-javascript text/xml text/css;

output_buffers  4 32k;
postpone_output 1460;

sendfile        on;
tcp_nopush      on;
tcp_nodelay     on;

keepalive_timeout       75 20;

ignore_invalid_headers  on;

include vhosts.d/*.conf;
}

So, the main nginx.conf includes every file in the vhosts.d/ subdirectory. One of my files was for serving PHP on localhost (was probably running phpMyAdmin) like this:

vhosts.d/00_localhost:

server {

  listen 127.0.0.1:80;
  server_name localhost;

  access_log /var/log/nginx/localhost.access_log main;
  error_log /var/log/nginx/localhost.error_log info;

  root /var/www/localhost/htdocs;
  index index.php index.html index.htm;

    location ~ .php$ {
        fastcgi_pass   127.0.0.1:8888;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/localhost/htdocs$fastcgi_script_name;
        fastcgi_param  QUERY_STRING     $query_string;
        fastcgi_param  REQUEST_METHOD   $request_method;
        fastcgi_param  CONTENT_TYPE     $content_type;
        fastcgi_param  CONTENT_LENGTH   $content_length;
  }
}

And then a local Django development server like this:

50_django.local:

server {

  listen  80;
  server_name django.local;

  access_log /var/log/nginx/django.access.log main;
  error_log /var/log/nginx/django.error.log info;

  root /var/www/django.local;

  location ~* ^.+\.(mpg|avi|mp3|swf|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|txt|tar|mid|midi|wav|rtf|mpeg)$ {
    access_log off;
    break;
  }

  location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|bmp|js)$ {
    expires 30d;
    break;
  }

  location / {
    fastcgi_pass unix:/var/www/django.local/server.sock;
    include fastcgi.conf;
  }

  location ^~ /admin/ {
    fastcgi_pass unix:/var/www/django.local/server.sock;
    include fastcgi.conf;
    access_log off;
    auth_basic "Welcome to admin";
  }
}

Finally, each of the virtual servers included a fastcgi.conf for each location.

fastcgi.conf:

fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;

fastcgi_param PATH_INFO         $fastcgi_script_name;
fastcgi_param REQUEST_METHOD    $request_method;
fastcgi_param QUERY_STRING      $query_string;
fastcgi_param CONTENT_TYPE      $content_type;
fastcgi_param CONTENT_LENGTH    $content_length;
fastcgi_param SERVER_PORT       $server_port;
fastcgi_param SERVER_PROTOCOL   $server_protocol;
fastcgi_param SERVER_NAME       $server_name;

fastcgi_param REQUEST_URI       $request_uri;
fastcgi_param DOCUMENT_URI      $document_uri;
fastcgi_param DOCUMENT_ROOT     $document_root;
fastcgi_param SERVER_ADDR       $server_addr;
fastcgi_param REMOTE_USER       $remote_user;
fastcgi_param REMOTE_ADDR       $remote_addr;
fastcgi_param REMOTE_PORT       $remote_port;
fastcgi_param SERVER_SOFTWARE   "nginx";
fastcgi_param GATEWAY_INTERFACE "CGI/1.1";

fastcgi_param UID_SET           $uid_set;
fastcgi_param UID_GOT           $uid_got;

I'm not sure all of the above were required, but that was another one of the reasons I switched to mod_wsgi... superior support and documentation :)

OTHER TIPS

Since this question was asked someone created a pip installable django package that will generate an apache or nginx vhost file for you from your settings.py

pip install django-vhost

Check it out here: https://bitbucket.org/djangostars/django-vhost

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top