Como usar o Django com FastCGI, SCGI ou AJP¶
Apesar da instalação atualmente preferida para rodar o Django ser Apache com mod_wsgi, muitas pessoas usam hospedagem compartilhada, onde protocolos como FastCGI, SCGI ou AJP são a única opção viável. Em algumas instalações, estes protocolos pode fornecer uma performance melhor que o mod_wsgi.
Note
Este documento foca primariamente no FastCGI. Outros protocolos, como SCGI
e AJP, são também suportados, através do pacote do Python flup
. Veja a
seção Protocolos abaixo para detalhes sobre SCGI e AJP.
Essencialmente, o FastCGI é uma forma eficiente de deixar uma aplicação externa servir páginas para um servidor Web. O servidor Web deleta as requisições Web vindas (via socket) para o FastCGI, que executa o código passando a resposta de volta ao servidor Web, que, por sua vez, passa-o de volta ao navegador do cliente.
Como mod_python, o FastCGI permite que o código fique na memória, permitindo requisições serem servidas sem tempo de inicialização. Diferentemente do mod_python (ou mod_perl), um processo FastCGI não roda dentro do processo do servidor Web, mas em um processo persistente separado.
Porque rodar código em um processo separado?
A modalidade tradicional mod_*
no Apache embute várias linguagens de
script (mais notavelmente PHP, Python e Perl) dentro do espaço do processo
de seu servidor Web. Embora isto diminua o tempo de inicialização – porque
o código não tem que ser lido em disco para cada requisição – ele vem com
custo de uso de memória. Para mod_python, por exemplo, todo processo Apache
carrega seu próprio interpretador Python, que consome um montante
considerável de RAM.
Devido a natureza do FastCGI, ainda é possível ter processos que rodem sob uma conta de usuário diferente do processo do servidor Apache. O que é um grande benefício para segurança em sistemas compartilhados, por que significa que você pode assegurar o seu código de outros usuários.
Pré-requisito: flup¶
Antes que você possa começar a usar o FastCGI com o Django, você precisará instalar o flup, uma biblioteca Python para lidar com FastCGI. A versão 0.5 ou as mais recentes devem funcionar muito bem.
Iniciando seu servidor FastCGI¶
O FastCGI opera sobre um modelo cliente-servidor, e na maioria dos casos você estará iniciando o processo FastCGI em seu próprio. Seu servidor Web (seja o Apache, lighttpd, ou qualquer outro) somente contata seu processo Django-FastCGI quando o servidor precisa que uma página dinâmica seja carregada. Porque o daemon já está rodando com o código em memoria, ele está pronto para servir uma resposta rapidamente.
Note
Se você está em sistema de hospedagem compartilhada, você provavelmente será forçado a usar o processo FastCGI gerenciado pelo servidor Web. Veja a seção abaixo, rodando o Django em processos gerenciados pelo servidor Web para mais informações.
Um servidor Web pode se conectar com um servidor FastCGI de uma das duas maneiras disponíveis: Ele pode usar cada um dos sockets de domínios Unix (um “pipe nomeado” em sistemas Win32), ou ele pode usar um socket TCP. O que você escolher é de sua preferência; um socket TCP é normalmente mais fácil devido aos problemas de permissões.
Para iniciar seu servidor, primeiro mude dentro do diretório de seu projeto
(aonde quer que seu manage.py esteja), e então rode o
comando runfcgi
:
./manage.py runfcgi [options]
Se vocÊ especificar help
como a única opção depois de runfcgi
,
ele irá mostrar uma lista de todas as opções disponíveis.
Você precisará especificar ainda um socket
, um protocolo
ou ambos
host
e porta
. Então, quando você configurar seu servidor Web, você
somente precisará apontá-lo para o host/port ou socket que você especificou
quando iniciou o servidor FastCGI. Veja os Exemplos, abaixo.
Protocolos¶
O Django suporta todos os protocolos que o flup suporta, fastcgi, SCGI e
AJP1.3 (o Apache JServ Protocol, versão 1.3). Selecione seu protocolo
preferido usando a opção protocol=<protocol_name>
com ./manage.py
runfcgi
– onde <protocol_name>
pode ser um dos: fcgi
(o padrão),
scgi
ou ajp
. Por exemplo:
./manage.py runfcgi protocol=scgi
Exemplos¶
Rodando um servidor em threads em uma porta TCP:
./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
Rodando um servidor preforked em um socket de domínio Unix:
./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
Executando sem o deamonizing (rodar em background) o processo (bom para debugging):
./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock maxrequests=1
Parando o daemon FastCGI¶
Se você tem o processo rodando em foreground, é bem fácil de pará-lo:
Simplesmente pressionando Ctrl-C
você parará e fechará o servidor FastCGI.
Entretanto, quando você está com processos em background, você precisará
recorrer ao comando kill
do Unix.
Se você especificr a opção pidfile
para o runfcgi
, você poderá
matar o daemon do processo FastCGI desta forma:
kill `cat $PIDFILE`
...onde $PIDFILE
é o pidfile
que você especificou.
Para facilitar o reinício do seu daemon FastCGI no Unix, tente este pequeno script shell:
#!/bin/bash
# Replace these three settings.
PROJDIR="/home/user/myproject"
PIDFILE="$PROJDIR/mysite.pid"
SOCKET="$PROJDIR/mysite.sock"
cd $PROJDIR
if [ -f $PIDFILE ]; then
kill `cat -- $PIDFILE`
rm -f -- $PIDFILE
fi
exec /usr/bin/env - \
PYTHONPATH="../python:.." \
./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
Configuração do Apache¶
Para usar o Django com o Apache e FastCGI, você precisará ter o Apache instalado e configurado, com mod_fastcgi instalado e habilitado. Consulte a documentação do Apache para instruções.
Uma vez que você tenha realizado a instalação, aponte o Apache para sua
instância do Django FastCGI editando o arquivo httpd.conf
(configuração do
Apache). Você precisará fazer duas coisas:
- Usar a diretiva
FastCGIExternalServer
para especificar a localização do seu servidor FastCGI. - Usar
mode_rewrite
para apontar as URLs para o FastCGI como se deve.
Especificando a localização do servidor FastCGI¶
A diretiva FastCGIExternalServer
diz ao Apache como encontrar seu servidor
FastCGI. Como a documentação do FastCGIExternalServer explica, você pode
especificar ambos socket
ou um host
. Aqui há alguns exemplos de ambos:
# Conecta o FastCGI via socket / pipe nomeado.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
# Conecta o FastCGI via um host/port TCP.
FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
Em ambos os casos, o arquivo /home/user/public_html/mysite.fcgi
na verdade
não tem de existir. Ele é somente uma URL usada pelo servidor Web internamente –
um hook para significando que as requisições para uma URL devem ser manipuladas
pelo FastCGI. (Mais sobre isto na próxima seção.)
Usando o mod_rewrite para apontar URLs no FastCGI¶
O segundo passo é dizer ao Apache para usar o FastCGI para URLs que combinam com
certos padrões. Para fazer isto, use o módulo mod_rewrite e redirecione as
URLs para mysite.fcgi
(ou o que você tenha especificado na diretiva
FastCGIExternalServer
, como explicado na seção anterior).
Neste exemplo, nós dizemos ao Apache para usar o FastCGI como manipulador de
qualquer requisição que não represente um arquivo do sistema de arquivos e não
com /media/
. Este é provavelmente caso mais comum, se você estiver usando o
admin do Django:
<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>
O Django automaticamente usará a versão pre-rewrite da URL quando estiver
construindo URLs com a tag de template {% url %}
(e métodos similares).
Configuração do lighttpd¶
O lighttpd é um servidor Web bem leve, comumente usado para servir arquivos estáticos. Ele suporta FastCGI nativamente e, esta, é uma boa escolha para servir ambas páginas estáticas e dinâmicas, se seu site não tem qualquer necessidade especifica relacionada ao Apache.
Esteja certo que mod_fastcgi
está na sua lista de módulos, em algum lugar
depois de mod_rewrite
e mod_access
, mas não depois do mod_accesslog
.
Você provavelmente precisará do mod_alias
, para servir as medias do admin.
Add the following to your lighttpd config file:
server.document-root = "/home/user/public_html"
fastcgi.server = (
"/mysite.fcgi" => (
"main" => (
# Use host / port instead of socket for TCP fastcgi
# "host" => "127.0.0.1",
# "port" => 3033,
"socket" => "/home/user/mysite.sock",
"check-local" => "disable",
)
),
)
alias.url = (
"/media" => "/home/user/django/contrib/admin/media/",
)
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/mysite.fcgi$1",
)
Executando múltiplos sites Django em um lighttpd¶
O lighttpd deixa você usar “configuração condicional” para permitir que a configuração seja customizada por host. Para especificar múltiplos sites FastCGI, é só adicionar um bloco condicional na sua configuração do FastCGI para cada site:
# Se o hostname for 'www.example1.com'...
$HTTP["host"] == "www.example1.com" {
server.document-root = "/foo/site1"
fastcgi.server = (
...
)
...
}
# Se o hostname for 'www.example2.com'...
$HTTP["host"] == "www.example2.com" {
server.document-root = "/foo/site2"
fastcgi.server = (
...
)
...
}
Você pode também rodar múltiplas instalações do Django no mesmo site,
simplesmente especificando múltiplas entradas na diretiva fastcgi.server
.
Adicione um FastCGI host para cada um.
Configuração do Cherokee¶
O Cherokee é um servidor Web muito rápido, flexível e fácil de configurar. Ele suporta tecnologias muito difundidas hoje: FastCGI, SCGI, PHP, CGI, SSI, TLS e conexões criptografadas por SSL, Vitual hosts, Authentication, encoding em tempo de execução, Load Balancing, compatível com arquivos de log do Apache, Data Base Balancer, Reverse HTTP Proxy e muito mais.
O projeto Cherokee provê uma documentação para configurar o Django com o Cherokee.
Rodando o Django em ambiente compartilhado com Apache¶
Muitos hospedeiros não permitem que você rode seus próprios daemons de servidor
ou editar o arquivo httpd.conf
. Nestes casos, ainda é possível rodar o
Django usando processos gerados pelo servidor Web.
Note
Se você está usando processos gerados pelo servidor Web, como explicado nesta seção não há necessidade de você iniciar o servidor FastCGI você mesmo. O Apache gerará um número de processos, escalando como ele precisar.
No seu diretório Web raiz, adicione isto ao arquivo chamado .htaccess
:
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
Então, crie um pequeno script para dizer ao Apache como gerar seu programa
FastCGI. Crie um arquivo mysite.fcgi
e coloque-o no seu diretório Web, e
assegure-se de torná-lo executável:
#!/usr/bin/python
import sys, os
# Adicione um caminho customizado do Python.
sys.path.insert(0, "/home/user/python")
# Mudando para o diretório do seu projeto. (Opcional.)
# os.chdir("/home/user/myproject")
# Setar a variável de ambiente DJANGO_SETTINGS_MODULE.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
Restartando o servidor gerado¶
Se você mudou qualquer código Python do seu site, você precisará dizer ao
FastCGI que o código mudou. Mas não há necessidade de reiniciar o Apache neste
caso. Ao invés, somente re-envie o mysite.fcgi
, ou edite o arquivo, desta
forma o timestamp do arquivo mudará. Quando o Apache ver que o arquivos foi
atualizado, ele irá reiniciar sua aplicação Django para você.
Se você tem acesso ao terminal em um sistema Unix, você pode realizar isto
facilmente usando o comando touch
:
touch mysite.fcgi
Servindo arquivos de mídia da administração¶
Regardless of the server and configuration you eventually decide to use, you will also need to give some thought to how to serve the admin media files. The advice given in the modpython documentation is also applicable in the setups detailed above.
Forçando o prefixo de URL para um valor em particular¶
Como muitas destas soluções baseadas no FastCGI requerem re-escrita de URL em
algum ponto dentro do servidor Web, a informação de caminho que o Django vê pode
não ser a mesma da URL original que foi passada. Isto é um problema se a
aplicação Django é servida sob um prefixo particular e você deseja que as URLs
geradas com a tag {% url %}
apareçam com o prefixo, ao invés da versão
re-escrita, que pode conter por exemplo, mysite.fcgi
.
O Django faz uma boa tentativa pra descobrir qual o verdadeiro nome de prefixo
do script que deve ser. Em particular, se o servidor Web seta o SCRIPT_URL
(específica para o mod_rewrite do Apache), ou REDIRECT_URL
(setada por
alguns servidores, incluindo Apache + mod_rewrite em algumas situações), o
Django encontrará o prefixo original automaticamente.
Nos casos onde o Django não encontra o prefixo corretamente e onde você quer que
o valor original seja usado nas URLs, você pode setar a configuração
FORCE_SCRIPT_NAME
no arquivo settings
principal. Isto seta o nome do
script uniformemente para toda URL servida via este arquivo settings. Assim,
você precisará usar arquivos de configurações diferentes, se você quiser
diferentes conjuntos de URLs para ter nomes de scripts diferentes neste caso,
mas está é uma situação rara.
Como um exemplo de como usá-lo, se sua configuração do Django está servindo
todas as URLs em '/'
e você esperava usar esta configuração, você poderia
setar FORCE_SCRIPT_NAME = ''
no seu arquivo settings.