2011年10月30日日曜日

Scientific Linux 6.1 で LAMP - Linux, Apache, MongoDB, Python(WSGI - Django)


このエントリーをはてなブックマークに追加


OpenStackのSwiftを触ってPythonを覚えたくなったので挑戦。

ついでなので前々から作ろうと思っていたとあるポータルをPythonで作ろうと思い立ち、環境周りの方針が決まったのでメモがてら公開。

可能な限り簡単に環境構築できるようにする。

*試してはないけど、RHEL6、CentOS6系でも同じように動くはず。


Scientific Linux 6.1 のインストール

ここら辺りを参考に。
>> RHEL6.1 のインストール
>> Scientific Linux 6.0 インストール
>> RHEL6/SL6/CentOS6 ネットワーク設定まとめ
>> KVM CentOS/Scientific/Fedoraをインターネット経由でインストールする

インストールタイプはBasic Serverを選択。インストール完了後にやること。


◆自動的に早いミラーを検索する。
[root@lamp ~]# yum install -y yum-plugin-fastestmirror.noarch


◆SELinuxを強制しない。将来的に公開するため無効にはしない。
[root@lamp ~]# vim /etc/sysconfig/selinux
SELINUX=permissive

◆SELinuxの問題をロギングする。permissive で発生するポリシー違反をロギングして問題を修正できるようにする。
[root@lamp ~]# yum install setroubleshoot-server setroubleshoot-doc


◆iptablesにルールを追加。http(s)のルールを追加する。
[root@lamp ~]# iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source    destination
1   104K  147M ACCEPT all  --  *  *   0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2      0     0 ACCEPT icmp --  *  *   0.0.0.0/0 0.0.0.0/0
3      0     0 ACCEPT all  --  lo *   0.0.0.0/0 0.0.0.0/0
4      2   104 ACCEPT tcp  --  *  *   0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5    156 23252 REJECT all  --  *  *   0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
[root@lamp ~]# iptables -I INPUT 5 -p tcp --dport 80 -j ACCEPT
[root@lamp ~]# iptables -I INPUT 6 -p tcp --dport 443 -j ACCEPT
[root@lamp ~]# iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source    destination
1   104K  147M ACCEPT all  --  *  *   0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2      0     0 ACCEPT icmp --  *  *   0.0.0.0/0 0.0.0.0/0
3      0     0 ACCEPT all  --  lo *   0.0.0.0/0 0.0.0.0/0
4      2   104 ACCEPT tcp  --  *  *   0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5      0     0 ACCEPT tcp  --  *  *   0.0.0.0/0 0.0.0.0/0 tcp dpt:80
6      0     0 ACCEPT tcp  --  *  *   0.0.0.0/0 0.0.0.0/0 tcp dpt:443
7    166 24730 REJECT all  --  *  *   0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
[root@lamp ~]# /etc/init.d/iptables save

◆パッケージのアップグレード
[root@lamp ~]# yum update -y

◆再起動
[root@lamp ~]# reboot


必要パッケージのインストール

◆gcc
pythonのライブラリ導入に必要

◆httpd
Apache本体

◆httpd-devel
pythonのライブラリ導入に必要

◆python-devel
pythonのライブラリ導入に必要

◆python-setuptools
easy_installを使うため

◆mod_wsgi
Apacheと連携させるために必要

コマンド一発で終わり。
[root@lamp ~]# yum install -y gcc httpd httpd-devel python-devel python-setuptools mod_wsgi


Pythonの開発環境設定 virtualenv/virtualenvwrapper

PythonはSL6.1標準を使います。
[root@lamp ~]# python -V
Python 2.6.6

◆virtualenv、virtualenvwrapperのインストール
[root@lamp ~]# easy_install virtualenv
[root@lamp ~]# easy_install virtualenvwrapper

◆専用ユーザの作成(任意)
[root@lamp ~]# useradd -g apache -d /var/www/wsgidev -m -s /bin/bash wsgidev
[root@lamp ~]# passwd wsgidev

◆virtualenv、virtualenvwrapperの設定
[root@lamp ~]# su - wsgidev
[wsgidev@lamp ~]$ pwd
/var/www/wsgidev

[wsgidev@lamp ~]$ vim ./.bash_profile
以下を追記
export WORKON_HOME=$HOME/.virtualenvs
source `which virtualenvwrapper.sh`

[wsgidev@lamp ~]$ logout
[root@lamp ~]# su - wsgidev
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/initialize
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/premkvirtualenv
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postmkvirtualenv
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/prermvirtualenv
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postrmvirtualenv
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/predeactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postdeactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/preactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/get_env_details
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/premkproject
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postmkproject
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/prermproject
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/postrmproject


ワーク作成とpipによるDjangoインストール

[wsgidev@lamp ~]$ mkvirtualenv portal
New python executable in portal/bin/python
Installing setuptools............done.
Installing pip...............done.
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/portal/bin/predeactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/portal/bin/postdeactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/portal/bin/preactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/portal/bin/postactivate
virtualenvwrapper.user_scripts creating /var/www/wsgidev/.virtualenvs/portal/bin/get_env_details
(portal)[wsgidev@lamp ~]$

(portal)[wsgidev@lamp ~]$ pip install django
Searching for pip
Downloading/unpacking django
  Downloading Django-1.3.1.tar.gz (6.5Mb): 6.5Mb downloaded
  Running setup.py egg_info for package django
Installing collected packages: django
  Running setup.py install for django
    changing mode of build/scripts-2.6/django-admin.py from 644 to 755
    changing mode of /var/www/wsgidev/.virtualenvs/portal/bin/django-admin.py to 755
Successfully installed django
Cleaning up...


MongoDBの導入

こちらを参考にインストール。

(proj-portal)[wsgi@lamp ~]$ deactivate
[wsgi@lamp ~]$ logout
[root@lamp ~]#

[root@lamp ~]# wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.1.tgz
[root@lamp ~]# tar zxvf mongodb-linux-x86_64-2.0.1.tgz
[root@lamp ~]# mkdir -p /opt/mongodb/dbf
[root@lamp ~]# mv mongodb-linux-x86_64-2.0.1 /opt/mongodb/
[root@lamp ~]# rm mongodb-linux-x86_64-2.0.1.tgz

◆起動とテスト
[root@lamp ~]# /opt/mongodb/mongodb-linux-x86_64-2.0.1/bin/mongod \
--dbpath /opt/mongodb/dbf \
--fork \
--logpath /var/log/mongodb.log --logappend

[root@lamp ~]# /opt/mongodb/mongodb-linux-x86_64-2.0.1/bin/mongo
MongoDB shell version: 2.0.1
connecting to: test

> show dbs
local   (empty)

> use sampledb1
switched to db sampledb1

> db.col1.save({"key1" : "date1"} );
> db.col1.save({"key2" : "date2"} );
> db.col1.save({"key3" : "date3"} );
> db.col1.find();
{ "_id" : ObjectId("4ead22e90a79f49b60760013"), "key1" : "date1" }
{ "_id" : ObjectId("4ead22ee0a79f49b60760014"), "key2" : "date2" }
{ "_id" : ObjectId("4ead22f40a79f49b60760015"), "key3" : "date3" }

> show collections
col1
system.indexes

> exit
bye


PythonとMongoDBの接続

◆pymongoの導入
[root@lamp ~]# su - wsgidev
[wsgidev@lamp ~]$ workon portal
(portal)[wsgidev@lamp ~]$ pip install pymongo
Downloading/unpacking pymongo
  Downloading pymongo-2.0.1.tar.gz (171Kb): 171Kb downloaded
  Running setup.py egg_info for package pymongo
Installing collected packages: pymongo
  Running setup.py install for pymongo
    building 'bson._cbson' extension
(省略)
Successfully installed pymongo
Cleaning up...

◆接続テスト
(portal)[wsgidev@lamp ~]$ python
Python 2.6.6 (r266:84292, May 20 2011, 16:42:11)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> from pymongo import Connection
>>> con = Connection('localhost',27017)
>>> db = con.sampledb1
>>> col = db.col1
>>> for data in col.find():
... print data
...
{u'key1': u'date1', u'_id': ObjectId('4ead22e90a79f49b60760013')}
{u'key2': u'date2', u'_id': ObjectId('4ead22ee0a79f49b60760014')}
{u'key3': u'date3', u'_id': ObjectId('4ead22f40a79f49b60760015')}


WSGIの設定

◆プロジェクトの作成
(portal)[wsgidev@lamp ~]$ mkdir pjportal
(portal)[wsgidev@lamp ~]$ cd pjportal/
(portal)[wsgidev@lamp pjportal]$ django-admin.py startproject pjportal
(portal)[wsgidev@lamp pjportal]$ ll
合計 4
drwxr-xr-x. 2 wsgidev apache 4096 10月 30 19:22 2011 pjportal

◆Apacheの設定
[root@lamp ~]# vim /etc/httpd/conf/httpd.conf

◆起動ユーザをwsgidevに変更
 238 #  NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
 239 #  when the value of (unsigned)Group is above 60000;
 240 #  don't use Group #-1 on these systems!
 241 #
 242 User wsgidev
 243 Group apache
 244

◆990行目のコメントを外す
 987 #
 988 # Use name-based virtual hosting.
 989 #
 990 NameVirtualHost *:80
 991 #
 992 # NOTE: NameVirtualHost cannot be used without a port specifier
 993 # (e.g. :80) if mod_ssl is being used, due to the nature of the
 994 # SSL protocol.

◆VirtualHostを定義
1003 WSGIPythonHome /var/www/wsgidev/.virtualenvs/portal
1004 <VirtualHost *:80>
1005     #ServerAdmin webmaster@dummy-host.example.com
1006     #DocumentRoot /www/docs/dummy-host.example.com
1007     ServerName lamp.example.com
1008     ErrorLog  logs/wsgi-error_log
1009     CustomLog logs/wsgi-access_log common
1010     WSGIScriptAlias / /var/www/wsgidev/pjportal/baz.wsgi
1011 </VirtualHost>

◆Djangoのロード
[wsgidev@lamp ~]$ vim pjportal/baz.wsgi
import os
import sys
import site

VIRTUALENV_SITE = '/var/www/wsgidev/.virtualenvs/portal/lib64/python2.6/site-packages'

site.addsitedir(VIRTUALENV_SITE)
sys.path.append('/var/www/wsgidev')
sys.path.append('/var/www/wsgidev/pjportal')
sys.path.append('/var/www/wsgidev/pjportal/pjportal/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'pjportal.settings'
os.environ['PYTHON_EGG_CACHE'] = '/var/www/.python-eggs'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()



起動と動作確認

◆apacheの起動
[root@lamp ~]# /etc/init.d/httpd start
httpd を起動中:                                            [  OK  ]


◆ブラウザからアクセス。設定が正しければ以下の画面が表示される。



とりあえずHello World

[root@lamp ~]# su - wsgidev

◆「portal」ワークに入る
[wsgidev@lamp ~]$ workon portal
(portal)[wsgidev@lamp ~]$ cd pjportal/pjportal/
(portal)[wsgidev@lamp pjportal]$ ls
__init__.py  __init__.pyc  manage.py  settings.py  settings.pyc  urls.py  urls.pyc

(portal)[wsgidev@lamp pjportal]$ pwd
/var/www/wsgidev/pjportal/pjportal

◆アプリケーションの作成
(portal)[wsgidev@lamp pjportal]$ python manage.py startapp helloapp
(portal)[wsgidev@lamp pjportal]$ ll
合計 32
-rw-r--r--. 1 wsgidev apache    0 10月 30 19:22 2011 __init__.py
-rw-r--r--. 1 wsgidev apache  133 10月 30 19:44 2011 __init__.pyc
drwxr-xr-x. 2 wsgidev apache 4096 10月 30 20:55 2011 helloapp
-rw-r--r--. 1 wsgidev apache  503 10月 30 19:22 2011 manage.py
-rw-r--r--. 1 wsgidev apache 5035 10月 30 19:22 2011 settings.py
-rw-r--r--. 1 wsgidev apache 2673 10月 30 19:32 2011 settings.pyc
-rw-r--r--. 1 wsgidev apache  571 10月 30 19:22 2011 urls.py
-rw-r--r--. 1 wsgidev apache  280 10月 30 19:44 2011 urls.pyc

(portal)[wsgidev@lamp pjportal]$ ll helloapp/
合計 12
-rw-r--r--. 1 wsgidev apache   0 10月 30 20:55 2011 __init__.py
-rw-r--r--. 1 wsgidev apache  57 10月 30 20:55 2011 models.py
-rw-r--r--. 1 wsgidev apache 383 10月 30 20:55 2011 tests.py
-rw-r--r--. 1 wsgidev apache  26 10月 30 20:55 2011 views.py

(portal)[wsgidev@lamp pjportal]$ pwd
/var/www/wsgidev/pjportal/pjportal

◆作成したアプリケーションをロード
(portal)[wsgidev@lamp pjportal]$ vim settings.py
111 INSTALLED_APPS = (
112     'django.contrib.auth',
113     'django.contrib.contenttypes',
114     'django.contrib.sessions',
115     'django.contrib.sites',
116     'django.contrib.messages',
117     'django.contrib.staticfiles',
118     # 以下を追加
119     'pjportal.helloapp',
120     # Uncomment the next line to enable the admin:
121     # 'django.contrib.admin',
122     # Uncomment the next line to enable admin documentation:
123     # 'django.contrib.admindocs',

◆URLディスパッチ
(portal)[wsgidev@lamp pjportal]$ vim urls.py
  7 urlpatterns = patterns('',
  8     # Examples:
  9     # url(r'^$', 'pjportal.views.home', name='home'),
 10     # url(r'^pjportal/', include('pjportal.foo.urls')),
 11
 12     # Uncomment the admin/doc line below to enable admin documentation:
 13     # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
 14
 15     # Uncomment the next line to enable the admin:
 16     # url(r'^admin/', include(admin.site.urls)),
 17     (r'^$', 'pjportal.helloapp.views.helloworld'),
 18 )

◆helloworlアプリを作成
(portal)[wsgidev@lamp pjportal]$ cd helloapp/
(portal)[wsgidev@lamp helloapp]$ pwd
/var/www/wsgidev/pjportal/pjportal/helloapp

(portal)[wsgidev@lamp helloapp]$ vim views.py
# Create your views here.
from django.http import HttpResponse

def helloworld(request):
    return HttpResponse("Hello World")


所感

Web開発はPHPやPerlでかじってるレベルなので環境構築だけで苦戦しまくり。でも何となく使ってみてDjangoってCL-Clackっぽいイメージ。

どっちが先なのかわからないけど、clack&markup のが断然わかりやすくて使いやすかったけどね!


参考サイト

CentOSで環境構築
virtualenv, virtualenvwrapper, pip を使う方法
Django の設定
Apache と mod_wsgi 環境で Django を使う方法
mod_wsgiで動かすときにmysite.settingsがimportできない問題
Djangoの基本チュートリアル ★かなりわかりやすい!

0 件のコメント:

コメントを投稿