원문(http://inocrazy.com/docs/8)에서 좀 더 깔끔하게 보실 수 있습니다.
Phusion Passenger (a.k.a. mod_rails)
Phusion Passenger는 네덜란드의 Phusion사에서 개발된 Apache web server의 module이다.(mod_rails로도 알려져있다.) PHP Application을 배포하는 것처럼, Rails Application에서 upload-and-go(업로드 후, 바로 실행)를 가능하게 해준다. 이 문서에서는 기존 Rails Deployment의 문제점을 살펴본 후, Passenger의 설치와 설정 방법에 대해서 알아볼 것이다.
Deployment : Rails vs PHP
Rails를 실전에 도입하는데 있어서 큰 장벽 중의 하나는 배포 환경의 문제이다. 최적화된 성능을 위해서 여러가지 선택을 해야만 한다. 우선 어떤 웹서버를 사용할 것인가(Apache 2.2 + mod_proxy_balancer or Nginx)를 결정해야 하고, 어플리케이션의 규모에 적절한 Mongrel 클라이언트의 개수를 결정해야 한다. 또한 이 Mongrel을 감시하기 위한 모니터링 데몬인 Monit이나 God 등도 설정해 주어야 한다. Mongrel의 경우, 하나의 클라이언트가 수십 메가씩 메모리를 점유하기 때문에 단순히 호스팅을 받아서는 구성할 수도 없다. 이 과정을 조금이라도 편하게 하기위해서 Capistrano를 도입해서 배포를 자동화할 수 있지만, 그를 위해서 또 다른 설정을 해야만 한다. 문제는 이러한 복잡한 설정을 통해서도 만족할만한 성능을 얻기가 어렵다는 것이다.
PHP의 경우, 개발한 어플리케이션을 호스팅 서버에 올리기만 하면 모든 배포가 끝나게 된다. 서버가 여러 대인 경우에도 rsync 한방이면 깔끔하게 정리된다. 가장 중요한 것은 이렇게 간단한 배포 방식에도 불구하고 꽤 괜찮은 성능을 보여준다는 것이다. 그에 반해서 Rails의 개발자는 너무도 많은 설정과 고민을 해야만 하고, 그에 반해 성능은 만족스럽지 못하다. Rails의 이러한 고민들이 어느날 혜성처럼 등장한 Phusion Passenger에 의해 해결되었다.
설치하기
Passenger는 두 가지 형태의 설치방법을 제공한다. gem 형태로 설치한 후에 빌드할 수도 있고, 소스코드를 다운받아서 빌드할 수도 있다. 설치방법은 두 방식 모두 비슷하므로, 여기서는 좀 더 쉬운 방식인 gem을 이용한 설치방법을 살펴보자. (소스로 설치하는 경우, 설치가 완료된 후에도 설치된 mod_passenger.so 모듈이나 passenger-spawn-server 실행파일에 접근해야 하기 때문에, 소스 디렉토리를 삭제하면 안된다.)
-
passenger gem을 설치한다.
- $ gem install passenger
-
passenger module을 빌드한다.
- $ passenger-install-apache2-module
Passenger에서는 사용하기 쉬운 passenger installer를 제공한다. shell에서 passenger-install-apache2-module 명령어를 실행시키면 아래 화면과 같이 installer의 시작 화면이 표시된다. 설치는 스텝별로 설명과 함께 진행되기 때문에 크게 어려운 점은 없을 것이다. Passenger 설치 시에 주의해야할 사항 몇 가지를 정리해보자.
passenger 설치 시작 화면
Apache bin 디렉토리를 PATH에 설정하기
passenger installer의 첫번째 단계는 설치에 필요한 소프트웨어를 찾는 것이다. 이때 Apache2 development header나 APR development header가 필요한데, Apache의 bin 디렉토리가 PATH에 설정되어있지 않을 경우, 아래와 같이 not found 메시지를 보여주게 된다. 또한 친절하게도 해당 문제에 대한 해결책까지 함께 보여준다. 하지만 Apache의 bin 디렉토리를 PATH에 추가함으로써 간단하게 해결할 수 있다.
Apache 관련 header를 찾을 수 없다는 메시지
- $ export PATH=/usr/local/apache2/bin:$PATH
boost/non_type.hpp 파일 문제
이 문제는 내 환경에서만 발생하는 것인지 모르지만, 여러 대의 서버에서 테스트한 결과 동일한 현상이 발생하여 정리해둔다. 위의 Apache 설정을 한 후에 passenger installer를 다시 실행시키면 필요한 소프트웨어가 모두 발견되고, Apache module을 컴파일하고 설치하는 스텝으로 넘어가게 된다. 그런데 컴파일 중 아래와 같은 오류 메시지가 발생하였다.
소스코드를 살펴보면 Boost C++ Library의 non_type.hpp 라는 파일을 찾지 못 해서 발생하는 에러인데, 해당 파일이 있어야할 ext/boost 디렉토리에 존재하지 않았다. 결국 이 문제를 해결하기 위해서 Boost C++ Library를 다운받아서 non_type.hpp 파일을 ext/boost 디렉토리에 복사한 후, 설치를 완료할 수 있었다.
설치가 완료된 후 아래와 같이 Apache의 httpd.conf 파일을 설정하는 방법에 대한 설명이 나오게 된다.
설정하기
httpd.conf 파일을 열어서 Passenger module의 설정을 추가한다.
- LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so
RailsSpawnServer /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-server
RailsRuby /usr/local/bin/ruby
VirtualHost의 Root로 설정하기
기본적으로 PHP Application을 설정하는 것과 동일하다. 여기서는 inocrazy.com 이라는 Rails Application을 설정하는 것을 가정해보자. Document Root는 /home/inocrazy/www/current/public 이며, inocrazy.com을 도메인으로 설정할 것이다. httpd.conf 파일에 VirtualHost 설정을 추가한다.
- <VirtualHost *:80>
ServerName inocrazy.com
DocumentRoot /home/inocrazy/www/current/public
</VirtualHost>
Sub 디렉토리로 설정하기
기존의 superkdk.com 사이트의 inocrazy라는 디렉토리에 inocrazy.com Rails Application을 설정하는 경우를 생각해보자. superkdk.com 사이트의 Document Root는 /home/superkdk/www이다. 우선적으로 할 일은 superkdk.com의 Document Root에 inocrazy라는 symlink를 만드는 것이다.
- $ ln -s /home/inocrazy/www/current/public /home/superkdk/www/inocrazy
그 후에 RailsBaseURI 옵션을 VirtualHost 설정에 추가해주면 된다.
- <VirtualHost *:80>
ServerName superkdk.com
DocumentRoot /home/superkdk/www
RailsBaseURI /inocrazy
</VirtualHost>
설정 옵션들
Passenger에서 사용할 수 있는 옵션들에 대해서 살펴보자.
RailsSpawnServer <filename>
Passenger spawn server의 경로를 설정한다. 위에서 살펴본 것처럼 설치 시에 정확한 경로를 알려주므로 해당 경로로 설정해두면 된다. 만약 이 옵션이 설정되지 않을 경우, $PATH 경로에서 passenger-spawn-server 라는 실행파일을 찾게된다.
RailsBaseURI <uri>
위에서 언급한 것처럼 Sub 디렉토리에 Rails Application을 설정하는 경우 설정한다. 각 VirtualHost마다 설정할 수 있다.
RailsAutoDetect <on|off>
Virtual Host의 Document Root가 Rails Application인지를 자동으로 찾아낼지 여부를 설정한다. 기본값은 on이다.
RailsAllowModRewrite <on|off>
Passenger가 mod_rewrite 규칙들을 override할지 여부를 설정한다. 기본값을 off이다.
RailsRuby <filename>
사용할 ruby 인터프리터의 경로를 설정한다.
RailsEnv <string>
기본적인 RAILS_ENV 변수값을 명시한다. 주의해야할 것은 이 옵션이 Global 옵션이라는 것이다. 따라서 각 Virtual Host마다 RAILS_ENV를 설정하기 위해서는, 각 Rails Application의 config/environment.rb에서 RAILS_ENV= 로 설정하는 방법 밖에 없다. (개인적으로 이 옵션은 VirtualHost 옵션으로 변경되어야 한다고 생각된다.)
RailsMaxPoolSize <integer>
동시에 실행될 Rails Application의 인스턴스 수를 설정한다. 이 값을 높게 설정할 경우, 메모리 사용량은 그만큼 높아지지만, 동시접속 처리능력은 (당연히) 증가하게 된다. Global 옵션으로서 기본값은 20이다.
(Phusion의 Ruby Enterprise Edition을 사용하면 메모리 사용량을 33% 정도 감소시킬 수 있다고 한다.)
RailsPoolIdelTime <integer>
Rails Application의 인스턴스의 유휴시간을 설정한다. 해당 유휴 시간 동안 아무 일도 하지않은 인스턴스는 메모리 보존을 위해서 shutdown되게 된다. 매뉴얼에서는 하나의 Rails 웹페이지에서 머무는 평균 시간의 2배 정도를 설정하는 것을 추천하고 있다. Global 옵션으로서 기본값은 120이다.
RailsUserSwitching <on|off>
사용자 전환을 실행할지 여부를 설정한다. 기본값은 on이다.
RailsDefaultUser <username>
사용자 전환이 실행될 경우, 전환한 사용자 계정을 설정한다. 기본값은 nobody이다.
Rails Application을 재시작하기
설정을 변경하거나 새롭게 배포한 후에는 Rails Application을 재시작해야한다. Mongrel 기반에서는 Mongrel 클라이언트를 모두 재시작하는 방법을 사용하였다. 그러면서 정확하게 죽지않는 개새끼(mongrel) 문제도 발생하곤 했다. Passenger에서는 두 가지 재시작 방법을 제공한다.
- Apache 재시작하기
- tmp/restart.txt 시간 갱신하기
첫 번째 방법은 (당연하지만) Apache를 재시작하는 것이다. 하지만 여러 개의 VirtualHost가 존재하는 서버에서 하나의 Rails Application을 재시작하기 위해서 매번 Apache를 재시작시키는 것은 부담되는 일이다. 이를 위해 Passenger에서는 특정 Rails Application만 재시작할 수 있는 방법을 제공한다. tmp 디렉토리에 restart.txt 파일을 생성하거나 갱신할 경우, 해당 Rails Application을 재시작한다. shell에서 touch 명령어를 통해서 간단하게 restart.txt를 생성하거나 갱신할 수 있다.
- $ touch tmp/restart.txt
결론
지금까지 Passenger의 기본적인 설치방법과 설정방법에 대해서 살펴보았다. Passenger의 등장으로 인해서 그동안 Rails Deployment에 있어서 장애로 여겨졌던 많은 부분들이 해소될 수 있을 것 같다. PHP만큼 쉽게 배포될 수 있는 환경이 구축됨에 따라서 Rails 개발자들도 좀 더 확산될 수 있을 것 같다. 또한 기존의 Rails Deployment 방식도 Passenger 기반으로 재설정되어야 할 것이다.
참조
이 글은 스프링노트에서 작성되었습니다.





::: 사람과 사람의 교감! 人터넷의 첫 시작! 댓글을 달아주세요! :::