ApacheのインストールからDjangoのデプロイまで
Amazon AMI + Apache + mod_wsgi + virtualenv + Django
Djangoのチュートリアル、開発用サーバを動かす(runserver)ところまでのものが多かったので、本番サーバで動くまでの手順をメモ。
動作環境は、Amazon AMI & Apache (+mod_wsgi)。
mod_wsgiはApacheのモジュールで、pythonのアプリケーションをApache上で動作させる。ちょっと古いmod_pythonは非推奨らしい。
今回は、virtualenvを使ってDjangoを動かすのに、pathの指定とかをApacheの設定ファイルに書く必要があって、そこを詳しくみてみる。
Apache+mod_wsgiのインストールと設定
必要モジュールをインストール
$ sudo yum install httpd httpd-devel mod_wsgi
Apacheのデフォルト設定ファイルは、/etc/httpd/conf/httpd.conf にあるけど、/etc/httpd/conf.d/ 直下にある*.conf も追加で読み込んでくれる。
mod_wsgiの動作確認として、/etc/httpd/conf.d/python.conf を作成する。
# mod_wsgiの読み込み LoadModule wsgi_module modules/mod_wsgi.so # /test というリクエストに対して、/var/www/cgi-bin/hello.py 返す。 WSGIScriptAlias /test /var/www/cgi-bin/hello.py
動作確認用に /var/www/cgi-bin/hello.py を作成。
/var/www/cgi-bin/hello.py
def application(environ, start_response): status = '200 OK' output = 'Hello World!' response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]
これで、apacheを起動して、http://yourServer.com/testにブラウザでアクセスすると、Hello World!と表示される。これでmod_wsgiの動作はオッケー。
(サーバーの名前がyourServer.comのとき)
# apacheを起動 $ sudo /etc/init.d/httpd start
virtualenv上でDjangoを動かす
pythonはパッケージのバージョンで依存関係が結構激しいので、プロジェクト単位でvirtualenv使うのがグッドノウハウ。
pip、virtualenvをインストールしたら、virtualenvを作成、virtualenvをアクティベートしたら、djangoをインストールする。
$ sudo easy_install pip $ sudo pip install virtualenv # virtualenvを作成 $ virtualenv ENV $ cd ENV $ . bin/activate # virtualenvを有効にする $ pip install django
djangoのプロジェクトは /var/www/cgi-bin/ に作成する。
$ sudo su - # cd /var/www/cgi-bin/ # django-admin.py startproject test_proj # cd /var/www/cgi-bin/test_proj/test_proj
プロジェクトを作ったときに、自動で作成される /var/www/cgi-bin/test_proj/test_proj/wsgi.py を編集。ここで、djangoを動かせるのはvirtualenv環境だけなので、virtualenvで使用するpythonのパスを教えてあげる。
/var/www/cgi-bin/test_proj/test_proj/wsgi.py
import os import site import sys # virtualenvのパッケージパス site.addsitedir("/home/ec2-user/ENV/lib/python2.6/site-packages") sys.path.append('/var/www/cgi-bin/test_proj') sys.path.append('/var/www/cgi-bin/test_proj/test_proj') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_proj.settings") # virtualenvの実行コードのパス activate_env = os.path.expanduser("/home/ec2-user/ENV/bin/activate_this.py") execfile(activate_env, dict(__file__=activate_env)) from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
さっき作った、apache設定ファイルに追加で書き込み。
/etc/httpd/conf.d/python.conf
# mod_wsgiの読み込み LoadModule wsgi_module modules/mod_wsgi.so # /test というリクエストに対して、/var/www/cgi-bin/hello.py 返す。 WSGIScriptAlias /test /var/www/cgi-bin/hello.py # /test_django というリクエストに対して、/var/www/cgi-bin/test_proj/test_proj/wsgi.py 返す。 WSGIScriptAlias /test_django /var/www/cgi-bin/test_proj/test_proj/wsgi.py # /var/www/cgi-bin/test_proj/test_projのアクセス制限を設定 <Directory /var/www/cgi-bin/test_proj/test_proj> Order deny,allow Allow from all </Directory>
# apacheを再起動 $ sudo /etc/init.d/httpd restart
これで、http://yourServer.com/test_proj にアクセスして It worked! と表示されればオッケー。
うまく動かないとき
- サーバーからレスポンスがないとき(ずっと読み込み)
サーバーのポート番号80が空いてないか、apacheが動いてない。
- Not Found (ページが見つかりません)
apacheは動いてるけど、ファイルがない or ディレクトリパスが間違ってる。
/etc/httpd/conf.d/python.conf で、正しくファイルのパスが指定できているかをみる。
- Internal Error (サーバー内部エラー)
パスも正しいけど、wsgi.pyの部分でエラーが発生している。
error_logを見て、エラーを特定する。
less /var/log/httpd/error_log
たぶん、import errorかpermission deniedがエラーの原因。
import errorは、必要なモジュールをinstallする。
activate_this.pyに対して、permission deniedがあったら、ディレクトリに対してpermissionを変更。ここで結構はまった。
$ sudo chmod 755 ec2-user/