Rails :: Deployment (Ubuntu - Apache - Subversion - Mongrel - Capistrano)

Posted by PunNeng, Sun May 06 00:01:00 UTC 2007

ได้ฤกษ์กลับมาฝั่ง Rails เสียที เพิ่งติดตั้ง Ubuntu 7.04 เสร็จใหม่ๆ เลย น่ารักมาก ปัญหาต่างๆ ที่เคยเจอมา ไม่มีอีกเลย แต่ยังต้องซ่อมไฟ led ของ wireless อีกนิดหน่อย ก็ไม่ใช่ปัญหาใหญ่อะไร

ปัญหาจริงๆ ที่เจอคือ Desktop Effects นี่นสิ ยังมีดื้อบ้างบางครั้ง ก็ปิดไปซะ ไม่ต้องใช้มัน

มาคราวนี้ เต็มๆ กับ Rails Deployment บน Ubuntu 7.04-Apache 2.2.x-Subverion 1.4.x-Mongrel(_cluster)-Capistrano เอาสูตรไปก่อน แล้วจะไล่อธิบายตามหลังอีกที

  • Apache 2.2 + PHP + MySQL
  • Apache + Subversion
  • The fellowship of Rails
  • Mongrel + Mongrel_cluster + Capistrano
  • Apache/Mongrel(_cluster) Configuration
  • Capistrano Configuration
  • Trac

ก่อนเริ่ม เอาบทนำไปก่อน ที่เราลองๆ กันอยู่บน localhost นั่นเป็นผลจากการรัน WEBrick หรือ Mongrel ก็แล้วแต่รสนิยมของแต่ละคน แต่ตอนรันจริงๆ ที่เป็น production ตัว server จะทำหน้าที่ต่างไปทันที และในความเป็นจริง เรายังต้องมองถึงเรื่อง Scalability อีกด้วย ใครจะไปรันงาน 1 งาน ต่อเครื่องหนึ่งเครื่อง จริงไหม? และอีกหนึ่งสิ่ง ที่ทำให้ ความวุ่นวายมันเพิ่มขึ้น คือ rails มีลักษณะ single-thread คือ รับได้แค่ทีละ request ณ เวลาหนึ่งๆ เท่านั้น

เนื่องจากสาเหตุเหล่านี้ เลยต้องหาตัวช่วยอย่าง Apache, Lighttpd หรือ Nginx มาช่วย เพราะมันรับ request ได้เยอะๆ ในเวลาหนึ่งๆ ซึ่งผมจะเรียกพวกนี้ว่า front-end web server ละกัน ซึ่งวิธีที่พวกนี้ช่วยได้คือรับ request ต่างๆ เข้ามา แล้วค่อยส่งไปยัง application server ตัวที่จะรันมันจริงๆ อย่าง FastCGI หรือ Mongrel ในด้าน scaling เรายังเพิ่ม application(app) server เพิ่มขึ้นได้อีก ก็ใช้ front-end we server นี่แหละ จะเป็นตัวกระจาย request มายัง app server ที่เพิ่มเข้ามา

มาดูเรื่องการกระจาย request กันบ้าง ช่วงแรกๆ ของ Rails เลย ในหนังสือ Agile Web Development with Rails First edition แนะให้ใช้ Lighttpd ต่อกับ FastCGI เพราะตัว Lighttpd มี load balancer ไว้ต่อกับ FastCGI อยู่แล้ว แต่ช่วงหลัง พี่ใหญ่อย่าง Apache ก็ได้พัฒนา load balancer ขึ้นมา ชื่อว่า mod_proxy_balancer ซึ่งเป็น module เสริมขึ้นมา ทำให้หลายๆ สำนัก เริ่มหันมาใช้ Apahce เป็น front-end web server แทน แต่จริงๆ แล้ว ยังมีทางเลือกอื่นอย่าง Litespeed หรือ Nginx แต่ก็ดูเหมือนยังเทียบรัศมีของ Apache ไม่ได้ แบบเก่า แบบใหม่

รูปจาก 1

มีคนมาบ่น1 รวมถึงอาจารย์ธวัชชัย ก็เปลี่ยนมาใช้ สูตร Apache+Mongrel เหมือนกัน ด้วยสาเหตุเรื่องความเสถียร

ผมเลือก Apache ตามเหตุผลข้างต้น และ Apache ก็มี module อย่าง mod_deflate ที่ช่วยบีบข้อมูลก่อนส่งออกไปยัง client ต่างๆ หรือ mod_proxy_balancer ที่ช่วยกระจาย request ไปยัง app server ต่างๆ ของเรา ถึงแม้ว่าเรื่องความเร็ว จะยังสู้ฝั่ง Lighttpd หรือ Nginx ไม่ได้ แต่มันก็ได้รับความเชื่อถือในด้านความเสถียร ซึ่งผมว่ามันสำคัญกว่าเรื่องความเร็วนะ และที่สำคัญสุดๆ เรื่องความเคยชิน :)

ผมเลือก Mongrel เพราะ Mongrel_cluster แค่นี้แหละครับ มันคุมง่ายดี ในกรณีที่ใช้ cluster ทำงาน แต่ในด้านความเร็ว เจ้านายผมเอง บอกว่า มันเร็วกว่า และเสถียรกว่า FastCGI ไว้หาหลักฐานเจอก่อน ว่ามันเร็วจริงๆ หรือเปล่า จะเอามาให้ดู

และที่สำคัญ หนังสือ Agile Web Development with Rails Second Edition ก็แนะนำให้ใช้สูตรนี้

Subversion เป็น Version Controller อีกตัวนึง ในกรณีนี้ จุดประสงค์ก็เพื่อให้มันเก็บ version ต่างๆ แล้ว ยังใช้งานรวมกับ Capistrano ด้วย เป็นตัวบอกกับ capistrano ว่า file ไหนบ้าง ที่มีการเปลี่ยนแปลง(โดย svn commit) แล้วตัว Capistrano นี้ ก็จะเอา file ที่มีการเปลี่ยนแปลงนั่นแหละ upload ไปยัง server ซึ่ง Capistrano นี้ ทำใช้ชีวิตเราง่ายดายเพียงแค่ปลายนิ้ววว(ผมว่ามีคนคิดลึก แต่ก็ใช่ครับ ผมคิดยังงั้นจริงๆ วะฮะฮ่า)

Subversion กับ Capistrano จำเป็นไหม?? ใช้ ftp ไม่ได้หรอ ?? ผมว่ามันก็ดีนะ ทำให้เราได้ backup file ที่ทำมา และยังแบ่งเป็น version อีกต่างหาก สำหรับ ftp ในบางกรณีต้องมีการ restart app server เราจะ remote หรือ ssh เข้าไป restart ทุกครั้งหรือ ???
ใช้ Capistrano ช่วยดีกว่า ไม่ต้องเสียเวลา เพียงแค่ปลายนิ้วสัมผัสส โอ้ววว

Trac เป็นระบบจัดการ wiki และการแสดงผลต่างๆ ในการพัฒนาชิ้นงาน ช่วยให้เราๆ รู้ว่าทำอะไรไปถึงไหนแล้ว โดยการแสดงผลหรือรายงานต่างๆ จะติดต่อผ่านทาง Subversion และเป็นตัวช่วยทำ projece management ย่อยๆ ด้วย

และนี่ เป็นเพียงอีกหนึ่งทางเลือก ยังมีสูตรอื่นๆ อีกหลายสูตร ทาง web server ตัวอื่นๆ ก็ยังพัฒนากันต่อไป ฝั่ง Mongrel หรือ FastCGI ก็ยังแข่งกันพัฒนาอยู่ ความสามารถของ Admin ก็ยังเป็นอีกหนึ่งปัจจัยหนึ่ง ที่เป็นตัวตัดสินว่าควรจะ scale มันแบบไหน ที่ออฟฟิศผมเอง ไม่ได้ใช้สูตรนี้เลย แต่ใช้ Litespeed+Mongrel_cluster และ Nginx+Mongrel_cluster แทน ซึ่งผมเองและเจ้านายก็พอใจในประสิทธิภาพของมัน

คราวหน้า จะมาลองกับ Nginx ครับ

อย่าลืม update repository กันก่อนละครับ
*** แยกให้ดีๆ นะครับ อันไหนเป็นฝั่ง client และอันไหนเป็นฝั่ง server เพราะทั้งหมดผมทำบนเครื่องผมเอง ***
สร้าง user

# sudo adduser username
$ sudo usermod -g www-data username
ให้ไปเพิ่ม usename ใน /etc/sudoers นะครับ ถ้าไม่อยู่ในกลุ่ม admin
username  ALL = (ALL) ALL 
แล้วก็ remote ไปใช้ แล้วจัดการ Apache 2.2 + PHP + MySQL ก่อน
$ sudo apt-get install apache2 libapache2-mod-php5
$ sudo apt-get install mysql-server phpmyadmin
ตั้ง username และ password หน่อย
$ mysqladmin -u root password your_password
$ mysql -u root -p
กรอก password ที่ใส่ลงไปนั่นแล
$ mysql> exit
ต่อไปก็ไปจัดการบน phpmyadmin ละกัน แล้วก็ออกจากโปรแกรม จัดการกับ Subversion ต่อ
$ sudo apt-get install subversion subversion-tools libsvn-dev libsvn1 libapache2-svn
สร้าง repository
$ sudo mkdir /var/svn
$ sudo svnadmin create /var/svn/

เพิ่ม permission

$ sudo chown -R www-data /var/svn
ให้สิทธิ์ user ที่อยู่ในกลุ่มเดียวกับ www-data จัดการได้ แค่นี้ก็ใช้งานได้แล้วสำหรับ Subversion test ดูง่ายๆ
$ svn co file:///var/svn/ /home/username/temp
ถ้าได้ น่าจะขึ้นว่า
Checked out revision 0.
ต่อไปจะจัดการกับต่อกับ Apache enable mod ให้กับ apache
$ sudo a2enmod dav
# sudo a2enmod dav_svn
$ sudo a2enmod rewrite
$ sudo a2enmod proxy
$ sudo a2enmod proxy_balancer
$ sudo a2enmod proxy_http
$ sudo a2enmod deflate
$ sudo a2enmod headers
เพิ่ม module ที่จะใช้เลย config ตัว apache หน่อย
# sudo gedit /etc/apache2/mods-enabled/dav_svn.conf
ใส่ไป แบบนี้
<location /svn>
  DAV svn
  SVNPath /var/svn
  # Access control policy
  # AuthzSVNAccessFile /etc/apache2/trac_svn_access
  # only authenticated users may access the repository
  # Require valid-user
  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /etc/apache2/dav_svn.passwd
  <limitexcept GET PROPFIND OPTIONS REPORT> 
        Require valid-user
  </limitexcept>

</location>
ใส่ password ให้กับ user
$ sudo htpasswd -c /etc/apache2/dav_svn.passwd username
$ sudo htpasswd /etc/apache2/dav_svn.passwd another_one
แล้วก็ใส่ password เอา ตามที่มันให้กรอก เอา -c ออกเวลา add user อื่นๆ เพิ่ม -c คือ create new file ถ้า add user อื่นๆ ด้วย -c มันจะสร้าง file อันใหม่ทับตัวเดิม restart apache
$ sudo /etc/init.d/apache2 restart
สำหรับวิธีใช้ subversion เดี๋ยวผมมาเล่าให้ฟังครับในครั้งต่อๆ ไป *** ผมแก้ไขเพิ่ม *** ผมเพิ่มส่วนของ anonymous user ให้อ่านได้อย่างเดียวใน repository ส่วนการเข้าถึง file ให้เอา comment ออก
AuthzSVNAccessFile /etc/apache2/trac_svn_access
Require valid-user
ซึ่ง trac_svn_access ผมจะแสดงใหัดูุด้านล่างอีกที(เปลีี่ยน่เป็นชืื่ออื่นได้) ต่อไปมาจัดการกับเหล่าพันธมิตรของ Rails
$ sudo apt-get install build-essential
เอาของจำเป็นที่ไว้ build ก่อน แล้วตามด้วยชุดของ Rails
$ sudo apt-get install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8
จริงๆ มันมีของ 1.9 แล้ว แต่ package ตัวอื่นๆ ยังไม่ได้ update ตาม เลยต้องใช้ 1.8 ไปก่อน แล้วเปลี่ยน link หน่อย
$ sudo ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
$ sudo ln -s /usr/bin/irb1.8 /usr/local/bin/irb
$ sudo ln -s /usr/bin/ri1.8 /usr/local/bin/ri
$ sudo ln -s /usr/bin/rdoc1.8 /usr/local/bin/rdoc
ตอนนี้ mysql ยังใช้ไม่ได้กับ ruby ลอง
$ irb
$ irb> require 'mysql'
$ LoadError: no such file to load -- mysql
$   from (irb#1):1:in `require'
$   from (irb#1):1
มันจะไม่ได้ ต้องติดตั้ง
$ sudo apt-get install libmysql-ruby1.8
แล้วลอง
$ irb
$ irb> require 'mysql'
$ => true
น่าจะได้แบบนี้ ต่อไป mail server ชื่อว่า Postfix
$ sudo apt-get install postfix
แล้วเลือก internet site แล้วก็ตั้งค่าไปตามเรื่อง ติดตั้ง rubygems
$ sudo apt-get install rubygems
แล้วติดตั้ง Rails ด้วย
$ sudo gem install rails --include-dependencies
ลองเรียก rails ดู ถ้าไม่เจอ command ให้ไปเพิ่มใน /etc/bash.bashrc ดังนี้
PATH=/var/lib/gems/1.8/bin/:"${PATH}"
ติดตั้ง ImageMagick ไว้จัดการรูปภาพ
# sudo apt-get install librmagick-ruby1.8 libmagick9-dev
$ sudo gem install rmagick
ชุดของ Rails ก็หมดแล้ว ตามด้วยชุดของ Mongrel
$ sudo gem install daemons gem_plugin mongrel mongrel_cluster capistrano --include-dependencies
ก็ติดตั้งตาม step ไป มา config กับ Mongrel\_cluster หน่อย ก่อนอื่นสร้าง project สำหรับ test มาก่อน ขั้นตอนนี้สำหรับฝั่ง client นะครับ ลองสร้างตามอันนี้ก็ได้ สมมติว่าสร้าง rails_test ไว้ใน /home/username/rails_projects
$ svn mkdir -m "" http://127.0.0.1/svn/rails_test
$ svn mkdir -m "" http://127.0.0.1/svn/rails_test/trunk
$ svn import -m "" /home/username/rails_projects/rails_test http://127.0.0.1/svn/rails_test/trunk
$ mv /home/username/rails_projects/rails_test /home/username/rails_projects/rails_test_backup
$ svn checkout http://127.0.0.1/svn/rails_test/trunk /home/username/rails_projects/rails_test
$ cd /home/username/rails_projects/rails_test
$ svn remove log/*
$ svn commit -m "removing all log files from subversion"
$ svn propset svn:ignore "*.log" log/
$ svn update log/
$ svn commit -m "Ignoring all files in /log/ ending in .log"
$ svn remove tmp/*
$ svn propset svn:ignore "*" tmp/
$ svn update tmp/
$ svn commit -m "Ignoring all files in /tmp/"
$ svn remove db/schema.rb
$ svn commit -m "Ignoring schema.rb"

พอ import เสร็จ มันยังมี log ของ local อยู่ ถ้าไม่เอาออก มันจะไปตีกับ log บน server เวลา upload ขึ้นไป และ file อื่นๆ ที่ทำนี่แล
-m คือ message มีอะไร note ก็ใส่ไป จะได้รู้ว่าเราทำอะไรไปบ้าง ในกรณีที่ต้องการเปลี่ยน user ตอน checkout(หรือ import)ให้แก้เป็น

$ svn checkout --username another_name --password another_password http://url source_folder
ถ้าเรา checkout มาด้วย user ไหน มันก็จะจำ user นั้นๆ ไปตลอด เวลาเรา commit หรือ update ไว้มาลุยกับ subversion เต็มๆ อีกที ต่อไป มาเพิ่ม config ให้ mongrel_cluster หน่อย ที่ฝั่ง server นะ
$ cd /home/username/rails_projects/rails_test
$ mongrel_rails cluster::configure -e production -p 5000 -a 127.0.0.1 -N 2 -c /var/www/apps/rails_test/current/

แล้วเราจะได้ config/mongrel_cluster.yml มาตัวนึง
แล้วไป config ค่าตอน boot

$ sudo mkdir /etc/mongrel_cluster
$ sudo ln -s /var/www/apps/rails_test/current/config/mongrel_cluster.yml /etc/mongrel_cluster/rails_test.yml
$ sudo cp /var/lib/gems/1.8/gems/mongrel_cluster-0.2.x/resources/mongrel_cluster /etc/init.d/
$ sudo chmod +x /etc/init.d/mongrel_cluster 
$ sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults

แล้วสั่ง

$ sudo mongrail_rails cluster::start

127.0.0.1:5000 และ 5001 จะถูก start นี่แล แต่ถ้าเจอมันฟ้องว่า sudo mongrel_rails cluster::start : command not found ให้ไปสร้าง softlink ไว้ที่ /usr/bin

$ sudo ln -s /var/lib/gems/1.8/bin/mongrel_rails /usr/bin/mongrel_rails
$ sudo ln -s /var/lib/gems/1.8/bin/mongrel_cluster_ctl /usr/bin/mongrel_cluster_ctl

อันหลังนี่ ต้องตรวจก่อนว่าใน /usr/bin มันมี mongrel_cluster_ctl หรือเปล่า ถ้าไม่มีก็สร้าง link ยิงไปหาก่อน ไม่งั้นตอน restart เครื่อง มันจะไม่รัน mongrel_cluster

จากนั้นมาต่อ Apache กับ Mongrel_cluster เสียหน่อย
เพิ่ม file ดังนี้ ใน /etc/apache2/site-available/

$ sudo gedit /etc/apache2/site-available/rails_test.com

ใส่

<VirtualHost *>

ServerName www.rails_test.com
DocumentRoot /var/www/apps/rails_test/current/public

<directory "/var/www/apps/rails_test/current/public">
  Options FollowSymLinks
  AllowOverride None
  Order allow,deny
  Allow from all
</directory>

<proxy balancer://mongrel_cluster>
  BalancerMember http://127.0.0.1:5000   
  BalancerMember http://127.0.0.1:5001
  Allow from localhost
</proxy>

RewriteEngine On

# Make sure people go to www.rails_test.com, not rails_test.com
RewriteCond %{HTTP_HOST} ^myapp.com$ [NC]
RewriteRule ^(.*)$ http://www.rails_test.com$1 [R=301,L]
# Yes, I've read no-www.com, but my site already has much Google-Fu on
# www.blah.com. Feel free to comment this out.

# Uncomment for rewrite debugging
#RewriteLog logs/myapp_rewrite_log
#RewriteLogLevel 9 

# Check for maintenance file and redirect all requests
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]

# Rewrite index to check for static
RewriteRule ^/$ /index.html [QSA] 

# Rewrite to check for Rails cached page
RewriteRule ^([^.]+)$ $1.html [QSA]

# Redirect all non-static requests to cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

# Deflate
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text javascript text/css
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# Uncomment for deflate debugging
#DeflateFilterNote Input input_info
#DeflateFilterNote Output output_info
#DeflateFilterNote Ratio ratio_info
#LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
#CustomLog logs/myapp_deflate_log deflate

ErrorLog /var/log/apache2/error.rails_test.log
CustomLog /var/log/apache2/access.rails_test.log combined
</VirtualHost>

โดยเพิ่มส่วนของ mod_proxy_balancer, mod_rewrite และ mod_deflate configuration เข้าไป
มันจะรับ request จากนั้นจะกระจายไปยัง port 5000 และ 5001 อีกที
แล้วสั่ง enable

$ sudo a2ensite rails_test.com
$ sudo /etc/init.d/apache2 restart

URL ไปเพิ่มเอาใน /etc/hosts ครับ

$ sudo gedit /etc/hosts

เพิ่ม

127.0.0.1   www.rails_test.com

เรียบร้อยแล้วก็ up ขึ้น host โดย capistrano

cap --apply-to /home/username/rails_project/rails_test

มันจะสร้าง file มาชุดนึง
แล้วเข้าไปแก้ใน config/deploy.rb ว่า

require 'mongrel_cluster/recipes'
set :application, "rails_test.com"
set :repository, "http://www.rails_test.com/svn/rails_test/trunk"
set :deploy_to, "/var/www/apps/rails_test"
set :user,      "username"
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"

role :web, "yourapp.com"
role :app, "yourapp.com"
role :db,  "yourapp.com", :primary => true

ก็ตามความหมายที่เซ็ตของมัน แล้วจะตามอธิบายในถายหลัง

require 'mongrel_cluster/recipes'

เอาไว้จัดการกับ spinner เพราะ default มันเป็นของ fcgi ต้องเปลี่ยนมาเป็น mongrel แทน แล้วติดตั้ง ssh และ termios เอาไว้ปิด password

# sudo apt-get install ssh
$ sudo gem install termios

แล้วลองติดตั้งดูง่ายๆ
*** ต้อง commit source files ขึ้นไป repository ให้หมดก่อน ***

$ cd /home/username/rails_projects/rails_test
$ svn add your_files_or_your_folder
$ svn commit -m "update my source files"
$ cap setup
$ cap cold_deploy

พอครั้งต่อๆ ไปก็

$ svn commit -m ""
$ cap deploy

นี่แหละครับ Capistrano ง่ายๆ แค่ปลายนิ้ว

แล้ววัดดวงกับ www.rails_test.com เลย

คั่นจังหวะหน่อย เดี๋ยวจะงง
หลังจากที่เรา svn commit ไปแล้ว source files จะไปอยู่บน server
พอสั่ง cap deploy มันจะทำการ copy จาก subversion บน server นั่นแหละ ไปวางใน path ที่กำหนดไว้ใน config/deploy.rb

เกือบแล้ว มาต่อด้วย Trac สำหรับ Subversion
*** อันนี้ไม่จำเป็นที่จะต้องติดตั้งครับ ***

$ sudo apt-get install trac libapache2-mod-python

แล้วเปิด mod_python ถ้ายังไม่ได้เปิด

$ sudo a2enmod mod_python

สร้าง source folder แล้วก็แก้ permission หน่อย

$ sudo mkdir /var/trac
$ sudo chown www-data /var/trac/

ถ้าหากเราไม่ใช้ Apache ต่อกับ Subversion สามารถใช้ Svnserve Server แทน สร้างตัว sunserve configuration ของ Subversion

$ sudo gedit /home/username/svn/conf/svnserve.conf

ใส่ไปว่า

anon-access = none 
auth-access = write
authz-db = /etc/apache2/trac_svn_access
realm = Your Repository

โดยตั้งให้ผู้ใช้ทั่วไปเข้าถึงไม่ได้ ถ้าผู้ใช้ที่ authenticate แล้ว ก็สามารถเขียน(และอ่าน) file ได้ และให้ authenticate ที่ file ที่กำหนดไว้ ซึ่งจะสร้างในภายหลัง โดยจะใช้กับ authentication ของ Trac แล้วต่อตัว Trac เข้ากับ Subversion โดยสร้าง environment ให้มันก่อน ก่อนอื่น ต้องสร้าง database ให้มันก่อน โดยเข้าไปสร้างใน phpmyadmin นั่นแหละ ตั้งชื่อ database ว่า trac
ตรงนี้ จริงๆ ฝั่ง MySQL ยังอยู่ในช่วงทดลองของ Trac ซึ่งผมอยากจะลองดูเฉยๆ ถ้าอยากได้ดีๆ คงต้องเป็น SQLite หรือ PostgreSQL รายละเอียด ดูได้จากเว็บของ Trac เลยครับ(ด้านบน แปะ link ไว้แล้ว)
ต้องติดตั้ง

$ sudo apt-get install python-mysqldb

เหมือนฝั่ง Ruby นั่นแล แล้วค่อยใส่

$ sudo trac-admin /var/trac/repos initenv

โดยมันจะให้ใส่

  • Project Name [My Project]> Your Project
  • Database connection string [sqlite:db/trac.db]> mysql://root:your_password@localhost:3306/trac
  • Repository type [svn]>
  • Path to repository [/path/to/repos]> /home/username/svn
  • Templates directory [/usr/share/trac/templates]>
ฝั่ง database ผมอยากลองใช้บน MySQL ครับ
ส่วนของ Subversion ผมใช้รวมเลย เลยเอามันตั้งแต่ path แรก ไม่ได้แยกเป็นแต่ละ project
แล้วสร้าง

$ sudo gedit /etc/apache2/trac_svn_access

เพื่อกำหนด permission แล้วใส่ไปว่า

[groups]
your_group = username, another_one

[/]
@your_group = rw

ใส่ group ไป แล้วกำหนดให้เขียนและอ่านได้ แล้วใส่ username กับ password เสียหน่อย

$ sudo htpasswd -c /etc/apache2/dav_trac_svn.passwd username
$ sudo htpasswd /etc/apache2/dav_trac_svn.passwd another_one

แล้วใส่ permission สำหรับ admin ให้มันหน่อย

$ sudo trac-admin /var/trac/repos permission add username TRAC_ADMIN

เรามีสิทธิ์ทุกอย่างแล้วบน trac
เพิ่ม สำหรับ user คนอื่น

$ sudo trac-admin /var/trac/repos permission add another_one WIKI_CREATE WIKI_MODIFY TICKET_CREATE TICKET_MODIFY

และ permission สำหรับ user ทั่วไป

$ sudo trac-admin /var/trac/repos permission remove anonymous WIKI_CREATE WIKI_MODIFY TICKET_CREATE TICKET_MODIFY

แล้วไปแก้ trac.ini

$ sudo gedit /var/trac/repos/conf/trac.ini

แก้ตามกลุ่ม

[project]
descr = your desciption
url = http://trac.yourapp.com/

[ticket]
restrict_owner = true

[trac]
authz_file = /etc/apache2/trac_svn_access

จากนั้น ไป config ฝั่ง apache ต่อ

$ sudo gedit /etc/apache2/sites-available/trac.yourapp.com

ใส่

<VirtualHost *>
ServerAdmin admin@yourapp.com
ServerName trac.yourapp.com

DocumentRoot /var/trac/repos
<Location />
    SetHandler mod_python
    PythonHandler trac.web.modpython_frontend
    PythonOption TracEnv /var/trac/repos
    PythonOption TracUriRoot /
    PythonPath "sys.path + ['/var/trac/repos']"
</Location>

ErrorLog  /var/log/apache2/error.trac.log
CustomLog /var/log/apache2/access.trac.log combined


<Location "/login" >
    AuthType Basic
    AuthName "Trac login"
    AuthUserFile /etc/apache2/dav_trac_svn.passwd
    Require valid-user
</Location>

</VirtualHost>

เพิ่ม /trac และ /login ให้เป็นอีก path นึงใน virtual host นี้ แล้วเปลี่ยน permission หน่อย

$ sudo chown -R www-data /var/trac/

เพิ่มใน /etc/hosts ด้วย

$ sudo gedit /etc/hosts

เพิ่ม

127.0.0.1   trac.rails_test.com

แล้วสั่ง enable กับ restart

$ sudo a2ensite trac.yourapp.com
$ sudo /etc/init.d/apache2 restart

แล้วลองเปิดกับ trac.yourapp.com ดูครับ
ในกรณีที่เราไม่ได้ต่อ Subversion กับ Apache แต่ใช้ Svnserve แทนโดยใช้กับ trac นี้ ใน deploy.rb ตรงส่วนของ repository ก็เปลี่ยนเป็น http://trac.yourapp.com/svn/rails_test/trunk แทน

โอ้วว ฝั่ง admin ดูเหมือนจะยังใช้ไม่ได้ ก็ที่เราใช้ command trac-admin สั่งเอานั่นแหละครับ มาเพิ่มต่อ

$ cd mkdir /home/username/downloads/
$ cd /home/username/downloads
$ svn co http://svn.edgewall.com/repos/trac/sandbox/webadmin/ trac_admin
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python ez_setup.py
$ sudo easy_install trac_admin/dist/TracWebAdmin-0.1.xdev_rxxxx-pyx.x.egg

check out มันลงมา ติดตั้งตัวช่วยหน่อย แล้วค่อยติดตั้ง ฝั่ง python ไม่คุ้นเลยแฮะ
แล้วแก้ trac.ini หน่อย

$ sudo vi /var/trac/repos/conf/trac.ini

เพิ่มว่า

[components]
webadmin.* = enabled

แล้ว restart apache

$ sudo /etc/init.d/apache2 restart

เข้าไปที่ trac ใหม่ แล้ว login เข้าเป็น admin ที่เราเซ็ตไว้ nav ด้านบน จะมีปุ่มทางขวาสุดโผล่มาเป็น admin โอ้วว เรียบร้อย

ปล. สำหรับ Subversion repository ที่ใช้คำสั่ง

$ svnadmin create /path/to/project

จริงๆ แล้วนิยมแยกเป็นแต่ละ project ไปเลย ซึ่งเราจะสามารถกำหนดได้ว่า user ไหน จะเข้าไปยุ่งกับ project ไหนได้บ้าง โดยการ authenticate ผ่านทาง Apache ตอนที่เซ็ต path แล้วใส่ username และ password นั่นแหละ แต่ของผม ผมใช้ของผมคนเดียว ผมเลยเอามันไว้รวมๆ เลย

1 Scaling Rails with Apache 2.2, mod_proxy_balancer and Mongrel
Setup a Production Ready Ruby on Rails Application Over Apache and Mongrel
Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You How to install Subversion version control server (with Apache support)
Apache 2.2, mod_proxy_balancer, & Mongrel on Ubuntu 6.06
Using Mongrel Cluster
Rmagick does not play well on Ubuntu
Installing Trac as CGI
Access Control for Subversion with Apache2 and Authz Version Control with Subversion
How to Use Rails With Subversion Trac Installation Guide
และอีกมากมาย =='

Special thanks: lindever กับการช่วยเหลือบนฝั่ง Ubuntu

Filed Under: Ruby on Rails | Tags: deployment howto ruby on rails

Comments

  1. จิตร์ทัศน์ 10.17.07 / 23PM

    ขอบคุณมากครับ ละเอียดจริงๆ

  2. PunNeng 10.18.07 / 12PM

    อาจารย์มะนาวมาเยี่ยมด้วย
    คาราวะ 1 จอก :)

codegent: we're hiring