忘れないようにメモっとく

機械学習とかプログラミングとか。

ApacheのインストールからDjangoのデプロイまで

Amazon AMI + Apache + mod_wsgi + virtualenv + Django

Djangoのチュートリアル、開発用サーバを動かす(runserver)ところまでのものが多かったので、本番サーバで動くまでの手順をメモ。

動作環境は、Amazon AMI & Apache (+mod_wsgi)。
mod_wsgiApacheのモジュールで、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 を作成する。

/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/