Django
- 開発サーバーを他のパソコンから見れるようにする
- mod_pythonでDjangoを動かす
- mod_wsgiでDjangoを動かす
- nginx + gunicornでDjangoを動かす
- reStructuredText(Docutils)を使うためのTips
- SSLを使う
- 静的ファイルを配信する
開発サーバーを他のパソコンから見れるようにする
Djangoの開発サーバーはデフォルトではlocalhostからしかアクセス出来ない。 他のパソコンから見れるようにするには、IPアドレスとポート番号を指定して 開発サーバーを起動すればよい。
例
python manage.py runserver 192.168.0.1:8000
mod_pythonでDjangoを動かす
apacheの設定例。 adminを利用する場合、adminで使用するcssなどのファイルを静的配信する必要がある。
<Location /> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE settings PythonDebug Off PythonPath "['/path/to/django_project'] + sys.path" </Location> Alias /media /opt/local/lib/python2.6/site-packages/django/contrib/admin/media <Location /media> SetHandler None </Location>
mod_wsgiでDjangoを動かす
mod_wsgiでDjangoを動かす場合、次のようなスクリプトを作成し、 apacheの設定ファイルでWSGIScriptAliasディレクティブを使って そのファイルを指定する。
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
apacheの設定例
WSGIScriptAlias / /path/to/wsgi_file Alias /media /opt/local/lib/python2.6/site-packages/django/contrib/admin/media <Location /media> SetHandler None </Location>
nginx + gunicornでDjangoを動かす
gunicornをつかってDjangoサーバを立ち上げる方法には、 Djangoのmanage.pyを使用する方法と、gunicorn_djangoコマンドを使用する方法がある。
manage.pyを使う場合は、まずsettingsモジュールのINSTALLED_APPSに'gunicorn'を追加する。
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'app1',
'gunicorn',
)
こうすることで、manage.pyで新たにrun_gunicornコマンドが使用可能となる。 gunicornプロセスを起動するには、次のようにコマンドを実行する。
./manage.py run_gunicorn [options]
gunicorn_djangoを使用する方法の場合、次のようにコマンドを実行する。
gunicorn_django [options] /path/to/settings.py
manage.pyを使う方法だと、settings.pyが標準以外の場所だとうまくいかない?ので、 gunicorn_djangoを使う方法をおすすめする。
オプションの与え方に関しては、コマンドライン引数で一つ一つオプションを指定してもよいが、 設定ファイルを作って--configオプションで指定する方法がスマート。
設定ファイルの例(設定ファイルの文法はpythonの文法そのもの)
bind = 'unix:/tmp/gunicorn_app1.sock'
backlog = 2048
workers = 1
worker_class = 'sync'
worker_connections = 1000
max_requests = 0
timeout = 30
keepalive = 2
debug = False
spew = False
preload_app = True
daemon = True
pidfile = '/var/run/gunicorn/app1.pid' # 起動前に/var/run/gunicornを作成する
user = 'app1_app'
group = 'nginx'
umask = 0002
logfile = '/var/log/gunicorn/app1.log' # 起動前に/var/log/gunicornを作成する
loglevel = 'info'
logconfig = None
proc_name = 'gunicorn_app1'
UNIXドメインソケットを使ってnginxと通信を行う場合、 nginxプロセスがそのソケットにアクセスする権限を持つ必要がある。 そのため、ここではgunicornプロセスのgidをnginx(ソケットのownerはapp1:nginxとなる)とし、umaskでグループの読み書きを許可している。 (gunicornプロセスのユーザをnginxプロセスと同一にすればumask=0022でもOK)
nginx側の設定では、upstreamディレクティブで上記gunicorn設定ファイルで指定したソケットのパスをサーバアドレスに指定する。 また、Djangoのadminを使用する場合、adminで使用する静的ファイルをnginxで配信するように設定する。
nginxの設定例
# /etc/nginx/nginx.conf user nginx; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; sendfile on; tcp_nopush on; keepalive_timeout 5; gzip on; include app1.conf; }
# /etc/nginx/app1.conf upstream app1-backend { server unix:/tmp/gunicorn_app1.sock fail_timeout=0; } server { listen 80; server_name app1.mydomain.com; access_log /var/log/nginx/app1.mydomain.com-access.log main; error_log /var/log/nginx/app1.mydomain.com-error.log info; location ~ /media/(.*)$ { alias /opt/local/lib/python2.7/site-packages/django/contrib/admin/media/$1; break; } location / { proxy_pass http://app1-backend; break; } }
reStructuredText(Docutils)を使うためのTips
Docutilsの設定を変更する
Docutilsの設定を変更する場合、プロジェクトのsettings.pyの中で、 RESTRUCTUREDTEXT_FILTER_SETTINGSというの名前の辞書を作成する。 例えば、見出しで使うタグをh1やh2ではなくh3やh4にする場合、 settings.py中に以下の行を追加する。
RESTRUCTUREDTEXT_FILTER_SETTINGS = dict(initial_header_level=3)
ディレクティブを定義する
reStructuredTextのディレクティブを自分で定義することができる。 ディレクティブを定義する手順は、
- docutils.parsers.rst.Directiveを継承したクラスでrunメソッドを定義する。
- runメソッドでdocutils.nodes.Nodeのサブクラスのインスタンスのリストを返す。
- 作成したディレクティブのクラスをdocutils.parsers.rst.directives.register_directiveで登録する。
ちなみに、このサイトはDjangoでreStructuredTextを使って書かれている。 プログラムのソースコードを記述したHTMLに自動的にクラスを追加するために、 以下のような拡張を行っている。
from docutils import nodes
from docutils.parsers.rst import directives
from docutils.parsers.rst import Directive
class ProgramLiteral(Directive):
required_arguments = 0
optional_arguments = 0
has_content = True
additional_classes = []
def run(self):
row_text = "\n".join(self.content)
literal_block = nodes.literal_block(row_text, row_text)
literal_block['classes'] += self.additional_classes
return [literal_block]
class PythonLiteral(ProgramLiteral):
additional_classes = ['python', 'sourcecode', 'prettyprint']
class RubyLiteral(ProgramLiteral):
additional_classes = ['ruby', 'sourcecode', 'prettyprint']
class BashLiteral(ProgramLiteral):
additional_classes = ['bash', 'sourcecode', 'prettyprint']
class HTMLLiteral(ProgramLiteral):
additional_classes = ['html', 'sourcecode', 'prettyprint']
class XMLLiteral(ProgramLiteral):
additional_classes = ['xml', 'sourcecode', 'prettyprint']
class JavascriptLiteral(ProgramLiteral):
additional_classes = ['javascript', 'sourcecode', 'prettyprint']
class LispLiteral(ProgramLiteral):
additional_classes = ['lisp', 'sourcecode', 'prettyprint']
directives.register_directive("python", PythonLiteral)
directives.register_directive("ruby", RubyLiteral)
directives.register_directive("bash", BashLiteral)
directives.register_directive("html", HTMLLiteral)
directives.register_directive("xml", XMLLiteral)
directives.register_directive("javascript", JavascriptLiteral)
directives.register_directive("lisp", LispLiteral)
参考URL
SSLを使う
djangosnippets.org で紹介されているスニペットを sslmiddleware.pyとして保存する。
プロジェクトのsettings.pyのMIDDLEWARE_CLASSESにsslmiddleware.SSLRedirectを追加する。
urls.py中でのSSLを使いたいURLのオプションに{'SSL' : True}を渡す。 例えば、/admin以下でSSLを使う場合、プロジェクトのurls.pyを以下のようにする。
urlpatterns = patterns('', (r'^admin/', include(admin.site.urls), {'SSL' : True}), )
静的ファイルを配信する
Djangoで静的ファイルを配信するには、 view関数django.views.static.serveを使う。
プロジェクトのurls.pyが置いてあるディレクトリの下にstaticという名前のディレクトリがあり、 その中のファイルを /static 以下に配置したい場合以下のように記述する。
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : /absolute_path/to/static/})
通常、この方法は開発サーバーのみで行う。 本番用の環境では、Apache等のウェブサーバー側の設定で静的ファイルの配信を行うようにする。
if settings.DEBUG:
import os
base = os.path.abspath( os.path.dirname(__file__) )
document_root = os.path.join(base, 'static')
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$',
'django.views.static.serve',
{'document_root' : document_root}),
)