ได้ฤกษ์กลับมาฝั่ง 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]>
ส่วนของ 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