0

CakePHP app กับ userdir

เวลาเอา web app ที่เขียนด้วย cakephp ไปใส่ใน userdir เช่น /home/veer/public_html/myapp (ซึ่งมักจะไปตรงกับ url http://hostname/~veer/myapp) มักจะมีปัญหากับ mod_rewrite ขึ้นมา แต่ก็แก้ไม่ยาก เพียงแต่แก้ .htaccess ใน myapp กับ myapp/app/webroot

เดิมทีจะเขียนไว้ประมาณนี้ (ใน myapp กับ myapp/app/webroot ไม่เหมือนกัน แต่ก็แก้เหมือนกัน)


   RewriteEngine on
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]

ก็แก้โดยใส่ RewriteBase เข้าไปเป็นแบบนี้


   RewriteEngine on
   RewriteBase    /~veer/myapp
   RewriteRule    ^$ app/webroot/    [L]
   RewriteRule    (.*) app/webroot/$1 [L]

เสร็จแล้ว

0

What I did for pylons app deployment.

I try to install my application created on Pylons on the Debian server that has already Apache2 + mod_wsgi + virtualenv + userdir.

What I did:

  1. creating prod.ini by copying development.ini.
  2. Change sqlalchemy.url
  3. set debug = false
  4. write a script in ~/public_html/wsgi-script as follow:
    import os
    import site
    os.environ['PYTHON_EGG_CACHE'] = "/home/myhome/egg"
    site.addsitedir("/home/myhome/wsgiapp/basa2")
    site.addsitedir("/home/myhome/pyenv/PYLONS-1/lib/python2.5/site-packages")
    
    from paste.deploy import loadapp
    APP_CONFIG = "/home/myhome/wsgiapp/basa2/prod.ini"
    application = loadapp("config:" + APP_CONFIG)
    
    
  5. I also modify this file: /home/vee/pydev/PYLONS-1/lib/python2.5/site-packages/Pylons-0.9.7rc3-py2.5.egg/pylons/wsgiapp.py by checking before the command:
    del  environ['pylons.pylons']

    following this changeset. (I use Pylons 0.9.7rc3)

The procedures above are just conclusion. I did a lot of trial and error. I also restart Apache web server (I must not have to do). By the ways, it works now.

0

xmlrpc ด้วย python บน apache

xmlrpc ด้วย python บน apache ผ่าน mod_wsgi. ใช้ xmlrpc บน python เขียนง่ายมากเลย ทั้ง client และ server ดูตัวอย่างจาก http://docs.python.org/library/simplexmlrpcserver.html ได้

แต่ว่า simple server นี้เป็น standalone server แล้วผมก็เจอปัญหาอีกว่า พอเรียกใช้จากเครื่องอื่น ที่ไม่ใช่เครื่องเดียวกันแล้วมั้นช้าๆ ชอบกล เลยเปลี่ยนไปใช้ wsgi-xmlrpc แทน มีคนเขียนไว้ให้แล้วด้วยดีจัง ^_^.

ทีแรกผมก็ลงโปรแกรมจาก easy_install เลย ใช้ easy_install wsgi_xmlrpc อะไรทำนองนี้ก็ลงได้ แต่เล่นไปเล่นมาเจอปัญหาภาษาไทย ก็เลยเอา source code จาก svn trunk ที่ google code มาใช้แทน ถึงตอนนี้ก็ยังใช้ได้ดีอยู่. (วิธีใช้ mod_wsgi กับ userdir เข้าไปดูที่ http://blog.vee-u.com/2008/06/18/mod_wsgi_userdir_ubuntu/ ได้
และ http://blog.vee-u.com/tag/wsgi/ ได้)

เพื่อที่ผมจะได้เอาไว้ดูเองในภายหลังด้วยจึงต้อง post ตัวอย่างสักหน่อย สมมุติ เขียน client แบบนี้

# -*- coding: UTF-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from xmlrpclib import ServerProxy
server = ServerProxy("http://localhost/test_service.wsgi", encoding="UTF-8")
print server.test_func("ดีจ๊ะ")

พอโปรแกรมทำงานแล้วได้ผลแบบนี้

ดีจ๊ะ ^_^

เวลาเขียน server ก็เขียนประมาณนี้ใน test_service.wsgi

import site
import os

os.environ['PYTHON_EGG_CACHE'] = "/somewhere/egg"
site.addsitedir("/home/vee/pyenv/WSGI-1/lib/python2.5/site-packages")

from wsgiref import simple_server
import wsgi_xmlrpc

def test_func(txt):
   return txt + " ^_^"

application = wsgi_xmlrpc.WSGIXMLRPCApplication(methods=[test_func])

^_^

0

แยก python environment: Pylons + virtualenv + mod_wsgi

ในเครื่องแม่ข่ายเครื่องหนึ่งอาจจะเป็นไปได้ว่ามีคนใช้ Pylons, Django, Turbogears แถมยังอาจจะใช้ package ของ Python ที่แตกต่างๆ กัน. ถ้าลงทุก package ที่ทุกคนต้องการไว้ในส่วนกลางหมดก็เป็นไปได้ว่าอาจจะมีบาง package ขัดแย้งกัน โดยเฉพาะโปรแกรมเดียวกันที่ต่าง version กัน. มากไปกว่านั้นก็อาจจะต้องกวนให้ sys admin ช่วย install ให้บ่อยๆ ด้วย หรือจะให้ทุกคนลง package ในส่วนกลางได้เองหมด ก็อาจจะกระทบกับเสถียรภาพโดยรวมของระบบ. อย่ากระนั้นเลยใช้ virtualenv มาแยก Python environment ของแต่ละคนเลยดีกว่า.

ผมก็เลยลองลง virtualenv ใช้กับ Apache + mod_wsgi + mod_userdir บน Ubuntu 8.04 บนเครื่องส่วนตัวของผมเองดู. ใน entry นี้ผมสมมุติว่าใช้ Apache + mod_wsgi + mod_userdir ได้อยู่แล้วนะครับ (และ มี setuptools ไว้แล้ว) แต่ถ้าสนใจเรื่องการติดตั้งระบบที่ใช้ mod_wsgi ผมก็เขียนเก็บไว้บ้างเหมือนกันที http://blog.vee-u.com/tag/mod_wsgi/

ลง virtualenv ง่ายมากเพียงสั่ง

$ sudo easy_install virtualenv

ก็เสร็จแล้ว

จากนั้นก็สร้าง directory ไว้ลง package ส่วนตัว โดยสั่ง

$ mkdir $HOME/pyenv

จากนั้นก็เข้าไปจัดการสร้าง enviroment โดย

$ cd $HOME/pyenv
$ virtualenv –no-site-packages BASELINE

แล้วก็สร้าง environment สำหรับลง Pylons
$ virtualenv –no-site-packages PYLONS-1

ก่อนลง Pylons ก็ activate environment นั้นก่อน
$ source PYLONS-1/bin/activate

พอ activate แล้ว prompt จะเปลี่นนเป็น (PYLONS-1)$

จากนั้นก็ลง Pylons 0.9.7 (รุ่นทดลอง), SQLAlchemy 0.4.8 และ PasteDeploy (ไม่ต้อง sudo ด้วย)
(PYLONS-1)$ easy install pylons==0.9.7rc2
(PYLONS-1)$ easy install sqlalchemy==0.4.8
(PYLONS-1)$ easy install PasteDeploy

แล้วก็ไฟล์สำหรับเรียก Pylons จาก wsgi ประมาณนี้

APP_CONFIG = "/home/veer/Develop/pylons/ex1/production.ini"
import os
os.environ['PYTHON_EGG_CACHE'] = "/home/veer/egg"
import sys

# บอกให้ python ไปหา package ที่ที่เราเตรียมไว้
sys.path = []
sys.path.append("/home/veer/pyenv/BASELINE/lib/python2.5/site-packages")
sys.path.append("/home/veer/pyenv/PYLONS-1/lib/python2.5/site-packages")
sys.path.append("/home/veer/Develop/pylons/ex1")

from paste.deploy import loadapp
application = loadapp("config:" + APP_CONFIG)

อะไรที่เขียน /home/veer ต่างๆ นี้คือสิ่งที่ใช้ในเครื่องผม เครื่องอื่นๆ ก็คงใช้ต่างๆ กันไป

เท่านี้เว็บของแต่ละคนก็มี environment ของตัวเองแล้ว อย่างในกรณีนี้ package ต่างๆ ก็มาอยู่ใน $HOME ของแต่ละ user แทนที่จะไปอยู่รวมๆ กันใน /usr/lib ผู้ใช้แต่ละคนก็แก้ได้ สะดวกสบาย

อ้างอิง http://code.google.com/p/modwsgi/wiki/VirtualEnvironments

2

Pylons + mod_wsgi + mod_userdir

ต่อจาก ติดตั้ง Django ก็ต่อด้วย Pylons. ก่อนหน้าจะพยายามลง Pylons ผมก็ลองพวก WSGIDaemonProcess ไปแล้ว แต่ว่าไม่สำเร็จก็เลยข้ามๆ ไป. ใช้ user เป็น www-data ก็ได้ :-P.

Pylons ก็มา pattern เดิมๆ ที่อ่านมาจาก http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons เริ่มด้วยสร้าง pylons.wsgi ใน /home/veer/public_html/wsgi-scripts ตามนี้

APP_CONFIG = "/home/veer/Develop/pylons/mydb4/production.ini"
import os
os.environ['PYTHON_EGG_CACHE'] = "/home/veer/egg"
import sys
sys.path.append("/home/veer/Develop/pylons/mydb4")
from paste.deploy import loadapp
application = loadapp("config:" + APP_CONFIG)

แล้วก็สร้าง /home/veer/egg เปลี่ยน permission ( mkdir /home/veer/egg; chmod 777 /home/veer/egg )

แล้วก็แก้สร้าง production.ini โดยการ copy มาจาก development.ini แล้วก็แก้ให้
full_stack = false
และ
debug = false

เท่านี้ก็น่าจะพอใช้ได้แล้ว

ลืมไปผมสร้าง app ไว้ใน /home/veer/Develop/mydb4 นะครับ พวก development.ini ก็อยู่ในนี้ล่ะ

2

mod_wsgi + userdir + Turbogears

อาจจะดูคลั่งๆ หน่อยแต่ mod_wsgi + userdir + Turbogears ก็ใช้ได้แล้ว. ด้วยพื้นฐานจากการใช้ mod_wsgi+userdir , การใช้ mod_wsgi กับ Turbogears และ การใช้ mod_wsgi กับ Turbogears แบบ non-root-mount. ก็แทบจะไม่ต้องทำอะไรแล้ว :-P.

แค่ copy ไฟล์ tg.wsgi ที่เคยอยู่ใน /home/veer/tg/tgapp/apache ไปไว้ใน /home/veer/public_html/wsgi-scripts/ แล้วก็แก้ prod.cfg ใน /home/veer/tg/tgapp นิดหน่อยที่ server.webpath ให้เปลี่ยนเป็น server.webpath=”/~veer/wsgi-scripts/tg.wsgi” เท่านี้ก็ใช้ซะงั้น.

สำหรับ Turbogears แล้วสำคัญมาที่ต้องใช้ tg.url เวลาเขียน URL ไม่ใส่ URL เอาเองตรงๆ (แบบที่ผมเคยทำ) … ไม่งั้นเวลามา deploy แบบนี้ก็แก้กันอ้วก :-P.

0

ทำให้ Turbogears + mod_wsgi ใช้งานกับ non-root mounted app

วิธีทำจริงๆ ก็อ่านจาก http://www.lucasmanual.com/mywiki/TurboGears#head-57ee578707aa057229eb1171a8e4aeb553bd6d3a มาเกือบหมด. แต่ว่าเขียนเสียหน่อยเพื่อความต่อเนื่องจากที่เขียนไว้เดิม. เริ่มจากแก้ /home/veer/tg/tgapp/apache/tg.wsgi:

import sys
sys.path.append('/home/veer/tg/tgapp')
sys.stdout = sys.stderr

import os
os.environ['PYTHON_EGG_CACHE'] = '/home/veer/tg/python-eggs'

import atexit
import cherrypy
import cherrypy._cpwsgi
import turbogears

# ข้างล่างเปลี่ยนไปใช้ fullpath แทนที่จะเขียน prod.cfg หรือ dev.cfg เฉยๆ
turbogears.update_config(configfile="/home/veer/tg/tgapp/prod.cfg", modulename="tgapp.config")
turbogears.config.update({'global': {'server.environment': 'production'}})
turbogears.config.update({'global': {'autoreload.on': False}})
turbogears.config.update({'global': {'server.log_to_screen': False}})

import tgapp.controllers

cherrypy.root = tgapp.controllers.Root()

if cherrypy.server.state == 0:
    atexit.register(cherrypy.server.stop)
    cherrypy.server.start(init_only=True, server_class=None)

application = cherrypy._cpwsgi.wsgiApp

จริงๆ แล้วก็แก้บรรทัดเดียว :-P … แต่ตอนลองทำงงเหมือนกัน

แล้วก็ไปสร้าง server.log ใน /home/veer/tg/tgapp/server.log อันนี้มีก็ทำแบบชั่วคราวๆ :-P (อีกแล้ว)

(อยู่ใน /home/veer/tg/tgapp)
touch server.log
chmod 777 server.log

ตามด้วยแก้ /home/veer/tg/tgapp/prod.cfg ทีแรกมันไม่มีให้แก้ก็เลยต้อง copy sample-prod.cfg มา

เพิ่ม server.webpath=”/first” เข้าไป (จริงมี # server.webpath=”” อยู่แล้ว ก็แค่เอา shape ออกแล้วใส่ /first ลงไป) แก้ path ของ server.log แบบนี้ args=”(‘/home/veer/tg/tgapp/server.log’,)” จากที่เดิมเขียนไว้ว่า args=”(‘server.log’,)”

ตามด้วยแก้ /etc/apache2/mod-enabled/mod-wsgi.conf เดิมเขียนไว้ว่า
WSGIScriptAlias / /home/veer/tg/tgapp/apache/tg.wsgi
ก็แก้เป็น
WSGIScriptAlias /first /home/veer/tg/tgapp/apache/tg.wsgi
เพื่อเปลี่ยนที่ mount

แล้วก็ restart apache ( /etc/init.d/apache restart ) จากนั้นพอเข้าไปดูใน localhost/first ก็ได้ผลตามต้องการ

… ต่อไปก็เป็น userdir T_T (เหมือนหา doc ไม่ค่อยเจอด้วย :-P)

3

mod_wsgi + userdir บน ubuntu 8.04

ผมอ่านเรื่องเปิดเทียบ web app tech ต่างๆ มา. เห้น mod_wsgi น่าสนใจดีก็เลยจะลองเล่นบ้าง (เอาแบบให้ใช้ได้หลายๆ user ด้วย น่าจะเหมาะกับ lab ดี) ก็เริ่มจากไปอ่าน http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines

แต่ก่อนจะทำตามตำรา ผมก็ลง mod_wsgi ก่อนเลย

 sudo aptitude install libapache2-mod-wsgi

ตามด้วย enable มันซะ

sudo a2enmod mod-wsgi

แปลกนะมีคำว่า mod ติดมาด้วย หาตั้งนาน :-P ปกติเวลาจะใช้ mod_userdir ก็แค่

sudo a2enmod userdir

(ไม่ใช่เหรอ? …. รวมถึง mod_rewrite และอื่นๆ ด้วย)

ด้วยความพิเศษของ Ubuntu/Debian นิดหน่อยๆ ไฟล์ที่ผมเข้าไปแก้คือ /etc/apache2/mods-enabled/userdir.conf ก็ดัดแปลงตามตัวอย่างอะนะแก้แล้วเป็นแบบนี้

<IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root

        <Directory /home/*/public_html/>
                AllowOverride FileInfo AuthConfig Limit
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        </Directory>

        RewriteEngine On
        RewriteCond %{REQUEST_URI} ^/~([^/]+)
        RewriteRule . - [E=APPLICATION_GROUP:~%1]

        <Directory /home/*/public_html/wsgi-scripts/>
                Options ExecCGI
                SetHandler wsgi-script
                WSGIApplicationGroup %{ENV:APPLICATION_GROUP}
        </Directory>
</IfModule>

เสร็จแล้วผมก็เข้าไปสร้าง folder ที่ /home/veer/public_html/wsgi-scripts พร้องเปลี่ยน permission เป็น 755 ตามด้วยเอา myapp.wsgi ตามตัวอย่างไปวางในนั้น

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]

จากนั้นก็ไปที่ web browser เรียก http://127.0.0.1/~vee/wsgi-scripts/myapp.wsgi (ตามรูป)

ขั้นตอนถัดไปก็จะลองลง Pylons และ Django ดู