rockdog-passenger 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (805) hide show
  1. data/DEVELOPERS.TXT +89 -0
  2. data/INSTALL +4 -0
  3. data/LICENSE +355 -0
  4. data/README +38 -0
  5. data/Rakefile +627 -0
  6. data/benchmark/ApplicationPool.cpp +52 -0
  7. data/benchmark/DummyRequestHandler.cpp +101 -0
  8. data/benchmark/accept_vs_socketpair_vs_named_pipes.rb +126 -0
  9. data/benchmark/dispatcher.rb +42 -0
  10. data/benchmark/overhead_of_password_checking.rb +81 -0
  11. data/benchmark/socket_connections_vs_persistent_pipe.rb +99 -0
  12. data/benchmark/unix_sockets_vs_pipes.rb +83 -0
  13. data/bin/passenger-config +40 -0
  14. data/bin/passenger-install-apache2-module +352 -0
  15. data/bin/passenger-make-enterprisey +78 -0
  16. data/bin/passenger-memory-stats +291 -0
  17. data/bin/passenger-spawn-server +53 -0
  18. data/bin/passenger-status +71 -0
  19. data/bin/passenger-stress-test +339 -0
  20. data/debian/compat +1 -0
  21. data/debian/control +21 -0
  22. data/debian/postinst +24 -0
  23. data/debian/prerm +2 -0
  24. data/doc/ApplicationPool algorithm.txt +398 -0
  25. data/doc/Architectural overview.txt +339 -0
  26. data/doc/Doxyfile +241 -0
  27. data/doc/Security of user switching support.txt +197 -0
  28. data/doc/Users guide.txt +2237 -0
  29. data/doc/definitions.h +5 -0
  30. data/doc/images/by_sa.png +0 -0
  31. data/doc/images/icons/README +5 -0
  32. data/doc/images/icons/callouts/1.png +0 -0
  33. data/doc/images/icons/callouts/10.png +0 -0
  34. data/doc/images/icons/callouts/11.png +0 -0
  35. data/doc/images/icons/callouts/12.png +0 -0
  36. data/doc/images/icons/callouts/13.png +0 -0
  37. data/doc/images/icons/callouts/14.png +0 -0
  38. data/doc/images/icons/callouts/15.png +0 -0
  39. data/doc/images/icons/callouts/2.png +0 -0
  40. data/doc/images/icons/callouts/3.png +0 -0
  41. data/doc/images/icons/callouts/4.png +0 -0
  42. data/doc/images/icons/callouts/5.png +0 -0
  43. data/doc/images/icons/callouts/6.png +0 -0
  44. data/doc/images/icons/callouts/7.png +0 -0
  45. data/doc/images/icons/callouts/8.png +0 -0
  46. data/doc/images/icons/callouts/9.png +0 -0
  47. data/doc/images/icons/caution.png +0 -0
  48. data/doc/images/icons/example.png +0 -0
  49. data/doc/images/icons/home.png +0 -0
  50. data/doc/images/icons/important.png +0 -0
  51. data/doc/images/icons/next.png +0 -0
  52. data/doc/images/icons/note.png +0 -0
  53. data/doc/images/icons/prev.png +0 -0
  54. data/doc/images/icons/tip.png +0 -0
  55. data/doc/images/icons/up.png +0 -0
  56. data/doc/images/icons/warning.png +0 -0
  57. data/doc/images/passenger_architecture.png +0 -0
  58. data/doc/images/passenger_architecture.svg +401 -0
  59. data/doc/images/phusion_banner.png +0 -0
  60. data/doc/images/spawn_server_architecture.png +0 -0
  61. data/doc/images/spawn_server_architecture.svg +655 -0
  62. data/doc/images/typical_isolated_web_application.png +0 -0
  63. data/doc/images/typical_isolated_web_application.svg +213 -0
  64. data/doc/template/horo.rb +613 -0
  65. data/ext/apache2/Application.h +526 -0
  66. data/ext/apache2/ApplicationPool.h +199 -0
  67. data/ext/apache2/ApplicationPoolServer.h +777 -0
  68. data/ext/apache2/ApplicationPoolServerExecutable.cpp +627 -0
  69. data/ext/apache2/Bucket.cpp +150 -0
  70. data/ext/apache2/Bucket.h +45 -0
  71. data/ext/apache2/Configuration.cpp +720 -0
  72. data/ext/apache2/Configuration.h +327 -0
  73. data/ext/apache2/DummySpawnManager.h +103 -0
  74. data/ext/apache2/Exceptions.h +240 -0
  75. data/ext/apache2/Hooks.cpp +1195 -0
  76. data/ext/apache2/Hooks.h +40 -0
  77. data/ext/apache2/LICENSE-CNRI.TXT +79 -0
  78. data/ext/apache2/Logging.cpp +60 -0
  79. data/ext/apache2/Logging.h +117 -0
  80. data/ext/apache2/MessageChannel.h +604 -0
  81. data/ext/apache2/SpawnManager.h +546 -0
  82. data/ext/apache2/StandardApplicationPool.h +817 -0
  83. data/ext/apache2/Utils.cpp +322 -0
  84. data/ext/apache2/Utils.h +365 -0
  85. data/ext/apache2/mod_passenger.c +33 -0
  86. data/ext/boost/LICENSE.TXT +23 -0
  87. data/ext/boost/VERSION.TXT +1 -0
  88. data/ext/boost/algorithm/string/case_conv.hpp +176 -0
  89. data/ext/boost/algorithm/string/compare.hpp +199 -0
  90. data/ext/boost/algorithm/string/concept.hpp +83 -0
  91. data/ext/boost/algorithm/string/config.hpp +28 -0
  92. data/ext/boost/algorithm/string/constants.hpp +36 -0
  93. data/ext/boost/algorithm/string/detail/case_conv.hpp +112 -0
  94. data/ext/boost/algorithm/string/detail/find_format.hpp +193 -0
  95. data/ext/boost/algorithm/string/detail/find_format_all.hpp +263 -0
  96. data/ext/boost/algorithm/string/detail/find_format_store.hpp +71 -0
  97. data/ext/boost/algorithm/string/detail/finder.hpp +646 -0
  98. data/ext/boost/algorithm/string/detail/formatter.hpp +94 -0
  99. data/ext/boost/algorithm/string/detail/replace_storage.hpp +159 -0
  100. data/ext/boost/algorithm/string/detail/sequence.hpp +200 -0
  101. data/ext/boost/algorithm/string/detail/util.hpp +106 -0
  102. data/ext/boost/algorithm/string/erase.hpp +844 -0
  103. data/ext/boost/algorithm/string/find_format.hpp +269 -0
  104. data/ext/boost/algorithm/string/finder.hpp +270 -0
  105. data/ext/boost/algorithm/string/formatter.hpp +103 -0
  106. data/ext/boost/algorithm/string/replace.hpp +928 -0
  107. data/ext/boost/algorithm/string/sequence_traits.hpp +193 -0
  108. data/ext/boost/algorithm/string/yes_no_type.hpp +33 -0
  109. data/ext/boost/assert.hpp +50 -0
  110. data/ext/boost/bind.hpp +1689 -0
  111. data/ext/boost/bind/arg.hpp +62 -0
  112. data/ext/boost/bind/bind_cc.hpp +117 -0
  113. data/ext/boost/bind/bind_mf_cc.hpp +227 -0
  114. data/ext/boost/bind/bind_template.hpp +345 -0
  115. data/ext/boost/bind/mem_fn_cc.hpp +103 -0
  116. data/ext/boost/bind/mem_fn_template.hpp +1020 -0
  117. data/ext/boost/bind/placeholders.hpp +68 -0
  118. data/ext/boost/bind/storage.hpp +475 -0
  119. data/ext/boost/call_traits.hpp +24 -0
  120. data/ext/boost/checked_delete.hpp +69 -0
  121. data/ext/boost/concept/assert.hpp +46 -0
  122. data/ext/boost/concept/detail/concept_def.hpp +51 -0
  123. data/ext/boost/concept/detail/concept_undef.hpp +5 -0
  124. data/ext/boost/concept/detail/general.hpp +66 -0
  125. data/ext/boost/concept/detail/has_constraints.hpp +48 -0
  126. data/ext/boost/concept/usage.hpp +43 -0
  127. data/ext/boost/concept_check.hpp +988 -0
  128. data/ext/boost/config.hpp +70 -0
  129. data/ext/boost/config/abi/borland_prefix.hpp +27 -0
  130. data/ext/boost/config/abi/borland_suffix.hpp +12 -0
  131. data/ext/boost/config/abi/msvc_prefix.hpp +8 -0
  132. data/ext/boost/config/abi/msvc_suffix.hpp +8 -0
  133. data/ext/boost/config/abi_prefix.hpp +25 -0
  134. data/ext/boost/config/abi_suffix.hpp +26 -0
  135. data/ext/boost/config/auto_link.hpp +368 -0
  136. data/ext/boost/config/compiler/borland.hpp +209 -0
  137. data/ext/boost/config/compiler/comeau.hpp +59 -0
  138. data/ext/boost/config/compiler/common_edg.hpp +62 -0
  139. data/ext/boost/config/compiler/compaq_cxx.hpp +19 -0
  140. data/ext/boost/config/compiler/digitalmars.hpp +67 -0
  141. data/ext/boost/config/compiler/gcc.hpp +149 -0
  142. data/ext/boost/config/compiler/gcc_xml.hpp +30 -0
  143. data/ext/boost/config/compiler/greenhills.hpp +28 -0
  144. data/ext/boost/config/compiler/hp_acc.hpp +95 -0
  145. data/ext/boost/config/compiler/intel.hpp +162 -0
  146. data/ext/boost/config/compiler/kai.hpp +35 -0
  147. data/ext/boost/config/compiler/metrowerks.hpp +111 -0
  148. data/ext/boost/config/compiler/mpw.hpp +51 -0
  149. data/ext/boost/config/compiler/pgi.hpp +25 -0
  150. data/ext/boost/config/compiler/sgi_mipspro.hpp +28 -0
  151. data/ext/boost/config/compiler/sunpro_cc.hpp +98 -0
  152. data/ext/boost/config/compiler/vacpp.hpp +60 -0
  153. data/ext/boost/config/compiler/visualc.hpp +191 -0
  154. data/ext/boost/config/no_tr1/complex.hpp +28 -0
  155. data/ext/boost/config/no_tr1/functional.hpp +28 -0
  156. data/ext/boost/config/no_tr1/memory.hpp +28 -0
  157. data/ext/boost/config/no_tr1/utility.hpp +28 -0
  158. data/ext/boost/config/platform/aix.hpp +33 -0
  159. data/ext/boost/config/platform/amigaos.hpp +15 -0
  160. data/ext/boost/config/platform/beos.hpp +26 -0
  161. data/ext/boost/config/platform/bsd.hpp +73 -0
  162. data/ext/boost/config/platform/cygwin.hpp +51 -0
  163. data/ext/boost/config/platform/hpux.hpp +84 -0
  164. data/ext/boost/config/platform/irix.hpp +31 -0
  165. data/ext/boost/config/platform/linux.hpp +98 -0
  166. data/ext/boost/config/platform/macos.hpp +78 -0
  167. data/ext/boost/config/platform/qnxnto.hpp +31 -0
  168. data/ext/boost/config/platform/solaris.hpp +21 -0
  169. data/ext/boost/config/platform/win32.hpp +58 -0
  170. data/ext/boost/config/posix_features.hpp +95 -0
  171. data/ext/boost/config/requires_threads.hpp +92 -0
  172. data/ext/boost/config/select_compiler_config.hpp +115 -0
  173. data/ext/boost/config/select_platform_config.hpp +90 -0
  174. data/ext/boost/config/select_stdlib_config.hpp +68 -0
  175. data/ext/boost/config/stdlib/dinkumware.hpp +106 -0
  176. data/ext/boost/config/stdlib/libcomo.hpp +46 -0
  177. data/ext/boost/config/stdlib/libstdcpp3.hpp +73 -0
  178. data/ext/boost/config/stdlib/modena.hpp +30 -0
  179. data/ext/boost/config/stdlib/msl.hpp +59 -0
  180. data/ext/boost/config/stdlib/roguewave.hpp +153 -0
  181. data/ext/boost/config/stdlib/sgi.hpp +111 -0
  182. data/ext/boost/config/stdlib/stlport.hpp +201 -0
  183. data/ext/boost/config/stdlib/vacpp.hpp +18 -0
  184. data/ext/boost/config/suffix.hpp +566 -0
  185. data/ext/boost/config/user.hpp +124 -0
  186. data/ext/boost/cstdint.hpp +448 -0
  187. data/ext/boost/date_time/adjust_functors.hpp +178 -0
  188. data/ext/boost/date_time/c_time.hpp +91 -0
  189. data/ext/boost/date_time/compiler_config.hpp +149 -0
  190. data/ext/boost/date_time/constrained_value.hpp +98 -0
  191. data/ext/boost/date_time/date.hpp +197 -0
  192. data/ext/boost/date_time/date_clock_device.hpp +77 -0
  193. data/ext/boost/date_time/date_defs.hpp +26 -0
  194. data/ext/boost/date_time/date_duration.hpp +147 -0
  195. data/ext/boost/date_time/date_duration_types.hpp +269 -0
  196. data/ext/boost/date_time/date_facet.hpp +775 -0
  197. data/ext/boost/date_time/date_format_simple.hpp +159 -0
  198. data/ext/boost/date_time/date_formatting.hpp +127 -0
  199. data/ext/boost/date_time/date_formatting_limited.hpp +121 -0
  200. data/ext/boost/date_time/date_formatting_locales.hpp +233 -0
  201. data/ext/boost/date_time/date_generator_formatter.hpp +263 -0
  202. data/ext/boost/date_time/date_generator_parser.hpp +329 -0
  203. data/ext/boost/date_time/date_generators.hpp +509 -0
  204. data/ext/boost/date_time/date_iterator.hpp +101 -0
  205. data/ext/boost/date_time/date_names_put.hpp +320 -0
  206. data/ext/boost/date_time/date_parsing.hpp +299 -0
  207. data/ext/boost/date_time/dst_rules.hpp +391 -0
  208. data/ext/boost/date_time/filetime_functions.hpp +78 -0
  209. data/ext/boost/date_time/format_date_parser.hpp +731 -0
  210. data/ext/boost/date_time/gregorian/conversion.hpp +73 -0
  211. data/ext/boost/date_time/gregorian/formatters.hpp +162 -0
  212. data/ext/boost/date_time/gregorian/formatters_limited.hpp +81 -0
  213. data/ext/boost/date_time/gregorian/greg_calendar.hpp +47 -0
  214. data/ext/boost/date_time/gregorian/greg_date.hpp +135 -0
  215. data/ext/boost/date_time/gregorian/greg_day.hpp +57 -0
  216. data/ext/boost/date_time/gregorian/greg_day_of_year.hpp +38 -0
  217. data/ext/boost/date_time/gregorian/greg_duration.hpp +38 -0
  218. data/ext/boost/date_time/gregorian/greg_duration_types.hpp +34 -0
  219. data/ext/boost/date_time/gregorian/greg_month.hpp +105 -0
  220. data/ext/boost/date_time/gregorian/greg_weekday.hpp +66 -0
  221. data/ext/boost/date_time/gregorian/greg_year.hpp +53 -0
  222. data/ext/boost/date_time/gregorian/greg_ymd.hpp +33 -0
  223. data/ext/boost/date_time/gregorian/gregorian.hpp +38 -0
  224. data/ext/boost/date_time/gregorian/gregorian_io.hpp +777 -0
  225. data/ext/boost/date_time/gregorian/gregorian_types.hpp +109 -0
  226. data/ext/boost/date_time/gregorian/parsers.hpp +91 -0
  227. data/ext/boost/date_time/gregorian_calendar.hpp +70 -0
  228. data/ext/boost/date_time/gregorian_calendar.ipp +219 -0
  229. data/ext/boost/date_time/int_adapter.hpp +507 -0
  230. data/ext/boost/date_time/iso_format.hpp +303 -0
  231. data/ext/boost/date_time/locale_config.hpp +31 -0
  232. data/ext/boost/date_time/microsec_time_clock.hpp +205 -0
  233. data/ext/boost/date_time/parse_format_base.hpp +29 -0
  234. data/ext/boost/date_time/period.hpp +377 -0
  235. data/ext/boost/date_time/period_formatter.hpp +196 -0
  236. data/ext/boost/date_time/period_parser.hpp +196 -0
  237. data/ext/boost/date_time/posix_time/conversion.hpp +93 -0
  238. data/ext/boost/date_time/posix_time/date_duration_operators.hpp +114 -0
  239. data/ext/boost/date_time/posix_time/posix_time.hpp +39 -0
  240. data/ext/boost/date_time/posix_time/posix_time_config.hpp +178 -0
  241. data/ext/boost/date_time/posix_time/posix_time_duration.hpp +82 -0
  242. data/ext/boost/date_time/posix_time/posix_time_io.hpp +246 -0
  243. data/ext/boost/date_time/posix_time/posix_time_system.hpp +68 -0
  244. data/ext/boost/date_time/posix_time/posix_time_types.hpp +55 -0
  245. data/ext/boost/date_time/posix_time/ptime.hpp +65 -0
  246. data/ext/boost/date_time/posix_time/time_formatters.hpp +289 -0
  247. data/ext/boost/date_time/posix_time/time_parsers.hpp +44 -0
  248. data/ext/boost/date_time/posix_time/time_period.hpp +29 -0
  249. data/ext/boost/date_time/special_defs.hpp +25 -0
  250. data/ext/boost/date_time/special_values_formatter.hpp +96 -0
  251. data/ext/boost/date_time/special_values_parser.hpp +159 -0
  252. data/ext/boost/date_time/string_convert.hpp +33 -0
  253. data/ext/boost/date_time/string_parse_tree.hpp +278 -0
  254. data/ext/boost/date_time/strings_from_facet.hpp +123 -0
  255. data/ext/boost/date_time/time.hpp +190 -0
  256. data/ext/boost/date_time/time_clock.hpp +83 -0
  257. data/ext/boost/date_time/time_defs.hpp +33 -0
  258. data/ext/boost/date_time/time_duration.hpp +281 -0
  259. data/ext/boost/date_time/time_facet.hpp +1263 -0
  260. data/ext/boost/date_time/time_formatting_streams.hpp +119 -0
  261. data/ext/boost/date_time/time_iterator.hpp +52 -0
  262. data/ext/boost/date_time/time_parsing.hpp +321 -0
  263. data/ext/boost/date_time/time_resolution_traits.hpp +140 -0
  264. data/ext/boost/date_time/time_system_counted.hpp +254 -0
  265. data/ext/boost/date_time/time_system_split.hpp +213 -0
  266. data/ext/boost/date_time/wrapping_int.hpp +163 -0
  267. data/ext/boost/date_time/year_month_day.hpp +45 -0
  268. data/ext/boost/detail/atomic_count.hpp +124 -0
  269. data/ext/boost/detail/atomic_count_gcc.hpp +68 -0
  270. data/ext/boost/detail/atomic_count_gcc_x86.hpp +84 -0
  271. data/ext/boost/detail/atomic_count_pthreads.hpp +96 -0
  272. data/ext/boost/detail/atomic_count_solaris.hpp +59 -0
  273. data/ext/boost/detail/atomic_count_sync.hpp +57 -0
  274. data/ext/boost/detail/atomic_count_win32.hpp +63 -0
  275. data/ext/boost/detail/bad_weak_ptr.hpp +59 -0
  276. data/ext/boost/detail/call_traits.hpp +164 -0
  277. data/ext/boost/detail/endian.hpp +73 -0
  278. data/ext/boost/detail/indirect_traits.hpp +487 -0
  279. data/ext/boost/detail/iterator.hpp +494 -0
  280. data/ext/boost/detail/lcast_precision.hpp +184 -0
  281. data/ext/boost/detail/limits.hpp +449 -0
  282. data/ext/boost/detail/reference_content.hpp +141 -0
  283. data/ext/boost/detail/shared_count.hpp +375 -0
  284. data/ext/boost/detail/sp_counted_base.hpp +81 -0
  285. data/ext/boost/detail/sp_counted_base_acc_ia64.hpp +150 -0
  286. data/ext/boost/detail/sp_counted_base_cw_ppc.hpp +170 -0
  287. data/ext/boost/detail/sp_counted_base_cw_x86.hpp +158 -0
  288. data/ext/boost/detail/sp_counted_base_gcc_ia64.hpp +157 -0
  289. data/ext/boost/detail/sp_counted_base_gcc_ppc.hpp +181 -0
  290. data/ext/boost/detail/sp_counted_base_gcc_sparc.hpp +166 -0
  291. data/ext/boost/detail/sp_counted_base_gcc_x86.hpp +173 -0
  292. data/ext/boost/detail/sp_counted_base_nt.hpp +107 -0
  293. data/ext/boost/detail/sp_counted_base_pt.hpp +135 -0
  294. data/ext/boost/detail/sp_counted_base_solaris.hpp +113 -0
  295. data/ext/boost/detail/sp_counted_base_sync.hpp +151 -0
  296. data/ext/boost/detail/sp_counted_base_w32.hpp +130 -0
  297. data/ext/boost/detail/sp_counted_impl.hpp +231 -0
  298. data/ext/boost/detail/sp_typeinfo.hpp +83 -0
  299. data/ext/boost/detail/workaround.hpp +202 -0
  300. data/ext/boost/enable_shared_from_this.hpp +73 -0
  301. data/ext/boost/function.hpp +66 -0
  302. data/ext/boost/function/detail/function_iterate.hpp +16 -0
  303. data/ext/boost/function/detail/maybe_include.hpp +267 -0
  304. data/ext/boost/function/detail/prologue.hpp +25 -0
  305. data/ext/boost/function/function_base.hpp +762 -0
  306. data/ext/boost/function/function_template.hpp +969 -0
  307. data/ext/boost/function_equal.hpp +28 -0
  308. data/ext/boost/get_pointer.hpp +29 -0
  309. data/ext/boost/implicit_cast.hpp +29 -0
  310. data/ext/boost/integer_traits.hpp +236 -0
  311. data/ext/boost/io/ios_state.hpp +431 -0
  312. data/ext/boost/io_fwd.hpp +67 -0
  313. data/ext/boost/is_placeholder.hpp +31 -0
  314. data/ext/boost/iterator.hpp +59 -0
  315. data/ext/boost/iterator/detail/config_def.hpp +135 -0
  316. data/ext/boost/iterator/detail/config_undef.hpp +25 -0
  317. data/ext/boost/iterator/detail/enable_if.hpp +86 -0
  318. data/ext/boost/iterator/detail/facade_iterator_category.hpp +200 -0
  319. data/ext/boost/iterator/detail/minimum_category.hpp +116 -0
  320. data/ext/boost/iterator/interoperable.hpp +50 -0
  321. data/ext/boost/iterator/iterator_adaptor.hpp +366 -0
  322. data/ext/boost/iterator/iterator_categories.hpp +188 -0
  323. data/ext/boost/iterator/iterator_facade.hpp +879 -0
  324. data/ext/boost/iterator/iterator_traits.hpp +92 -0
  325. data/ext/boost/iterator/reverse_iterator.hpp +69 -0
  326. data/ext/boost/iterator/transform_iterator.hpp +188 -0
  327. data/ext/boost/lexical_cast.hpp +1205 -0
  328. data/ext/boost/limits.hpp +146 -0
  329. data/ext/boost/mem_fn.hpp +389 -0
  330. data/ext/boost/mpl/always.hpp +39 -0
  331. data/ext/boost/mpl/and.hpp +60 -0
  332. data/ext/boost/mpl/apply.hpp +225 -0
  333. data/ext/boost/mpl/apply_fwd.hpp +107 -0
  334. data/ext/boost/mpl/apply_wrap.hpp +200 -0
  335. data/ext/boost/mpl/arg.hpp +131 -0
  336. data/ext/boost/mpl/arg_fwd.hpp +28 -0
  337. data/ext/boost/mpl/assert.hpp +370 -0
  338. data/ext/boost/mpl/aux_/adl_barrier.hpp +48 -0
  339. data/ext/boost/mpl/aux_/arg_typedef.hpp +31 -0
  340. data/ext/boost/mpl/aux_/arity.hpp +39 -0
  341. data/ext/boost/mpl/aux_/arity_spec.hpp +67 -0
  342. data/ext/boost/mpl/aux_/common_name_wknd.hpp +34 -0
  343. data/ext/boost/mpl/aux_/config/adl.hpp +40 -0
  344. data/ext/boost/mpl/aux_/config/arrays.hpp +30 -0
  345. data/ext/boost/mpl/aux_/config/bind.hpp +33 -0
  346. data/ext/boost/mpl/aux_/config/compiler.hpp +64 -0
  347. data/ext/boost/mpl/aux_/config/ctps.hpp +30 -0
  348. data/ext/boost/mpl/aux_/config/dtp.hpp +46 -0
  349. data/ext/boost/mpl/aux_/config/eti.hpp +47 -0
  350. data/ext/boost/mpl/aux_/config/gcc.hpp +23 -0
  351. data/ext/boost/mpl/aux_/config/has_apply.hpp +32 -0
  352. data/ext/boost/mpl/aux_/config/has_xxx.hpp +33 -0
  353. data/ext/boost/mpl/aux_/config/integral.hpp +38 -0
  354. data/ext/boost/mpl/aux_/config/intel.hpp +21 -0
  355. data/ext/boost/mpl/aux_/config/lambda.hpp +32 -0
  356. data/ext/boost/mpl/aux_/config/msvc.hpp +21 -0
  357. data/ext/boost/mpl/aux_/config/msvc_typename.hpp +26 -0
  358. data/ext/boost/mpl/aux_/config/nttp.hpp +41 -0
  359. data/ext/boost/mpl/aux_/config/overload_resolution.hpp +29 -0
  360. data/ext/boost/mpl/aux_/config/pp_counter.hpp +26 -0
  361. data/ext/boost/mpl/aux_/config/preprocessor.hpp +39 -0
  362. data/ext/boost/mpl/aux_/config/static_constant.hpp +25 -0
  363. data/ext/boost/mpl/aux_/config/ttp.hpp +41 -0
  364. data/ext/boost/mpl/aux_/config/use_preprocessed.hpp +19 -0
  365. data/ext/boost/mpl/aux_/config/workaround.hpp +19 -0
  366. data/ext/boost/mpl/aux_/full_lambda.hpp +350 -0
  367. data/ext/boost/mpl/aux_/has_apply.hpp +32 -0
  368. data/ext/boost/mpl/aux_/has_type.hpp +23 -0
  369. data/ext/boost/mpl/aux_/include_preprocessed.hpp +42 -0
  370. data/ext/boost/mpl/aux_/integral_wrapper.hpp +93 -0
  371. data/ext/boost/mpl/aux_/lambda_arity_param.hpp +25 -0
  372. data/ext/boost/mpl/aux_/lambda_support.hpp +169 -0
  373. data/ext/boost/mpl/aux_/msvc_never_true.hpp +34 -0
  374. data/ext/boost/mpl/aux_/na.hpp +95 -0
  375. data/ext/boost/mpl/aux_/na_assert.hpp +34 -0
  376. data/ext/boost/mpl/aux_/na_fwd.hpp +31 -0
  377. data/ext/boost/mpl/aux_/na_spec.hpp +175 -0
  378. data/ext/boost/mpl/aux_/nested_type_wknd.hpp +48 -0
  379. data/ext/boost/mpl/aux_/nttp_decl.hpp +35 -0
  380. data/ext/boost/mpl/aux_/preprocessed/gcc/and.hpp +69 -0
  381. data/ext/boost/mpl/aux_/preprocessed/gcc/apply.hpp +169 -0
  382. data/ext/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp +52 -0
  383. data/ext/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp +84 -0
  384. data/ext/boost/mpl/aux_/preprocessed/gcc/arg.hpp +123 -0
  385. data/ext/boost/mpl/aux_/preprocessed/gcc/bind.hpp +561 -0
  386. data/ext/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp +52 -0
  387. data/ext/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp +558 -0
  388. data/ext/boost/mpl/aux_/preprocessed/gcc/or.hpp +69 -0
  389. data/ext/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp +105 -0
  390. data/ext/boost/mpl/aux_/preprocessed/gcc/quote.hpp +123 -0
  391. data/ext/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp +101 -0
  392. data/ext/boost/mpl/aux_/preprocessor/def_params_tail.hpp +105 -0
  393. data/ext/boost/mpl/aux_/preprocessor/enum.hpp +62 -0
  394. data/ext/boost/mpl/aux_/preprocessor/filter_params.hpp +28 -0
  395. data/ext/boost/mpl/aux_/preprocessor/params.hpp +65 -0
  396. data/ext/boost/mpl/aux_/preprocessor/sub.hpp +65 -0
  397. data/ext/boost/mpl/aux_/static_cast.hpp +27 -0
  398. data/ext/boost/mpl/aux_/template_arity.hpp +189 -0
  399. data/ext/boost/mpl/aux_/template_arity_fwd.hpp +23 -0
  400. data/ext/boost/mpl/aux_/type_wrapper.hpp +47 -0
  401. data/ext/boost/mpl/aux_/value_wknd.hpp +89 -0
  402. data/ext/boost/mpl/aux_/yes_no.hpp +58 -0
  403. data/ext/boost/mpl/bind.hpp +547 -0
  404. data/ext/boost/mpl/bind_fwd.hpp +99 -0
  405. data/ext/boost/mpl/bool.hpp +39 -0
  406. data/ext/boost/mpl/bool_fwd.hpp +33 -0
  407. data/ext/boost/mpl/eval_if.hpp +71 -0
  408. data/ext/boost/mpl/has_xxx.hpp +272 -0
  409. data/ext/boost/mpl/identity.hpp +45 -0
  410. data/ext/boost/mpl/if.hpp +135 -0
  411. data/ext/boost/mpl/int.hpp +22 -0
  412. data/ext/boost/mpl/int_fwd.hpp +27 -0
  413. data/ext/boost/mpl/integral_c.hpp +51 -0
  414. data/ext/boost/mpl/integral_c_fwd.hpp +32 -0
  415. data/ext/boost/mpl/integral_c_tag.hpp +26 -0
  416. data/ext/boost/mpl/lambda.hpp +29 -0
  417. data/ext/boost/mpl/lambda_fwd.hpp +57 -0
  418. data/ext/boost/mpl/limits/arity.hpp +21 -0
  419. data/ext/boost/mpl/logical.hpp +21 -0
  420. data/ext/boost/mpl/next.hpp +19 -0
  421. data/ext/boost/mpl/next_prior.hpp +49 -0
  422. data/ext/boost/mpl/not.hpp +51 -0
  423. data/ext/boost/mpl/or.hpp +61 -0
  424. data/ext/boost/mpl/placeholders.hpp +100 -0
  425. data/ext/boost/mpl/protect.hpp +55 -0
  426. data/ext/boost/mpl/quote.hpp +140 -0
  427. data/ext/boost/mpl/size_t.hpp +25 -0
  428. data/ext/boost/mpl/size_t_fwd.hpp +28 -0
  429. data/ext/boost/mpl/void.hpp +76 -0
  430. data/ext/boost/mpl/void_fwd.hpp +26 -0
  431. data/ext/boost/next_prior.hpp +51 -0
  432. data/ext/boost/non_type.hpp +27 -0
  433. data/ext/boost/noncopyable.hpp +36 -0
  434. data/ext/boost/none.hpp +28 -0
  435. data/ext/boost/none_t.hpp +24 -0
  436. data/ext/boost/operators.hpp +943 -0
  437. data/ext/boost/optional.hpp +18 -0
  438. data/ext/boost/optional/optional.hpp +922 -0
  439. data/ext/boost/optional/optional_fwd.hpp +22 -0
  440. data/ext/boost/preprocessor/arithmetic/add.hpp +51 -0
  441. data/ext/boost/preprocessor/arithmetic/dec.hpp +288 -0
  442. data/ext/boost/preprocessor/arithmetic/inc.hpp +288 -0
  443. data/ext/boost/preprocessor/arithmetic/sub.hpp +50 -0
  444. data/ext/boost/preprocessor/array/data.hpp +28 -0
  445. data/ext/boost/preprocessor/array/elem.hpp +29 -0
  446. data/ext/boost/preprocessor/array/size.hpp +28 -0
  447. data/ext/boost/preprocessor/cat.hpp +35 -0
  448. data/ext/boost/preprocessor/comma_if.hpp +17 -0
  449. data/ext/boost/preprocessor/config/config.hpp +70 -0
  450. data/ext/boost/preprocessor/control/detail/while.hpp +536 -0
  451. data/ext/boost/preprocessor/control/expr_iif.hpp +31 -0
  452. data/ext/boost/preprocessor/control/if.hpp +30 -0
  453. data/ext/boost/preprocessor/control/iif.hpp +34 -0
  454. data/ext/boost/preprocessor/control/while.hpp +312 -0
  455. data/ext/boost/preprocessor/debug/error.hpp +33 -0
  456. data/ext/boost/preprocessor/detail/auto_rec.hpp +293 -0
  457. data/ext/boost/preprocessor/detail/check.hpp +48 -0
  458. data/ext/boost/preprocessor/detail/is_binary.hpp +30 -0
  459. data/ext/boost/preprocessor/empty.hpp +17 -0
  460. data/ext/boost/preprocessor/enum.hpp +17 -0
  461. data/ext/boost/preprocessor/enum_params.hpp +17 -0
  462. data/ext/boost/preprocessor/facilities/empty.hpp +21 -0
  463. data/ext/boost/preprocessor/facilities/identity.hpp +23 -0
  464. data/ext/boost/preprocessor/identity.hpp +17 -0
  465. data/ext/boost/preprocessor/inc.hpp +17 -0
  466. data/ext/boost/preprocessor/iterate.hpp +17 -0
  467. data/ext/boost/preprocessor/iteration/detail/bounds/lower1.hpp +99 -0
  468. data/ext/boost/preprocessor/iteration/detail/bounds/upper1.hpp +99 -0
  469. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +1342 -0
  470. data/ext/boost/preprocessor/iteration/iterate.hpp +82 -0
  471. data/ext/boost/preprocessor/list/adt.hpp +73 -0
  472. data/ext/boost/preprocessor/list/append.hpp +40 -0
  473. data/ext/boost/preprocessor/list/detail/fold_left.hpp +279 -0
  474. data/ext/boost/preprocessor/list/detail/fold_right.hpp +277 -0
  475. data/ext/boost/preprocessor/list/fold_left.hpp +303 -0
  476. data/ext/boost/preprocessor/list/fold_right.hpp +40 -0
  477. data/ext/boost/preprocessor/list/for_each_i.hpp +65 -0
  478. data/ext/boost/preprocessor/list/reverse.hpp +40 -0
  479. data/ext/boost/preprocessor/list/transform.hpp +49 -0
  480. data/ext/boost/preprocessor/logical/and.hpp +30 -0
  481. data/ext/boost/preprocessor/logical/bitand.hpp +38 -0
  482. data/ext/boost/preprocessor/logical/bool.hpp +288 -0
  483. data/ext/boost/preprocessor/logical/compl.hpp +36 -0
  484. data/ext/boost/preprocessor/punctuation/comma.hpp +21 -0
  485. data/ext/boost/preprocessor/punctuation/comma_if.hpp +31 -0
  486. data/ext/boost/preprocessor/repeat.hpp +17 -0
  487. data/ext/boost/preprocessor/repetition/detail/for.hpp +536 -0
  488. data/ext/boost/preprocessor/repetition/enum.hpp +66 -0
  489. data/ext/boost/preprocessor/repetition/enum_binary_params.hpp +54 -0
  490. data/ext/boost/preprocessor/repetition/enum_params.hpp +41 -0
  491. data/ext/boost/preprocessor/repetition/for.hpp +306 -0
  492. data/ext/boost/preprocessor/repetition/repeat.hpp +825 -0
  493. data/ext/boost/preprocessor/repetition/repeat_from_to.hpp +87 -0
  494. data/ext/boost/preprocessor/seq/elem.hpp +304 -0
  495. data/ext/boost/preprocessor/seq/enum.hpp +288 -0
  496. data/ext/boost/preprocessor/seq/for_each_i.hpp +61 -0
  497. data/ext/boost/preprocessor/seq/seq.hpp +44 -0
  498. data/ext/boost/preprocessor/seq/size.hpp +548 -0
  499. data/ext/boost/preprocessor/slot/detail/def.hpp +49 -0
  500. data/ext/boost/preprocessor/slot/detail/shared.hpp +247 -0
  501. data/ext/boost/preprocessor/slot/slot.hpp +32 -0
  502. data/ext/boost/preprocessor/stringize.hpp +33 -0
  503. data/ext/boost/preprocessor/tuple/eat.hpp +57 -0
  504. data/ext/boost/preprocessor/tuple/elem.hpp +385 -0
  505. data/ext/boost/preprocessor/tuple/rem.hpp +72 -0
  506. data/ext/boost/preprocessor/tuple/to_list.hpp +62 -0
  507. data/ext/boost/range/as_literal.hpp +131 -0
  508. data/ext/boost/range/begin.hpp +132 -0
  509. data/ext/boost/range/config.hpp +54 -0
  510. data/ext/boost/range/const_iterator.hpp +64 -0
  511. data/ext/boost/range/detail/common.hpp +117 -0
  512. data/ext/boost/range/detail/implementation_help.hpp +99 -0
  513. data/ext/boost/range/detail/sfinae.hpp +77 -0
  514. data/ext/boost/range/detail/str_types.hpp +38 -0
  515. data/ext/boost/range/difference_type.hpp +29 -0
  516. data/ext/boost/range/distance.hpp +34 -0
  517. data/ext/boost/range/empty.hpp +34 -0
  518. data/ext/boost/range/end.hpp +131 -0
  519. data/ext/boost/range/functions.hpp +27 -0
  520. data/ext/boost/range/iterator.hpp +72 -0
  521. data/ext/boost/range/iterator_range.hpp +643 -0
  522. data/ext/boost/range/mutable_iterator.hpp +64 -0
  523. data/ext/boost/range/rbegin.hpp +65 -0
  524. data/ext/boost/range/rend.hpp +65 -0
  525. data/ext/boost/range/reverse_iterator.hpp +40 -0
  526. data/ext/boost/range/size.hpp +36 -0
  527. data/ext/boost/range/size_type.hpp +78 -0
  528. data/ext/boost/range/value_type.hpp +34 -0
  529. data/ext/boost/ref.hpp +178 -0
  530. data/ext/boost/shared_ptr.hpp +619 -0
  531. data/ext/boost/src/pthread/exceptions.cpp +146 -0
  532. data/ext/boost/src/pthread/once.cpp +51 -0
  533. data/ext/boost/src/pthread/thread.cpp +709 -0
  534. data/ext/boost/src/pthread/timeconv.inl +130 -0
  535. data/ext/boost/src/tss_null.cpp +34 -0
  536. data/ext/boost/src/win32/exceptions.cpp +124 -0
  537. data/ext/boost/src/win32/thread.cpp +629 -0
  538. data/ext/boost/src/win32/timeconv.inl +130 -0
  539. data/ext/boost/src/win32/tss_dll.cpp +72 -0
  540. data/ext/boost/src/win32/tss_pe.cpp +269 -0
  541. data/ext/boost/static_assert.hpp +122 -0
  542. data/ext/boost/thread.hpp +21 -0
  543. data/ext/boost/thread/condition.hpp +16 -0
  544. data/ext/boost/thread/condition_variable.hpp +21 -0
  545. data/ext/boost/thread/detail/config.hpp +94 -0
  546. data/ext/boost/thread/detail/move.hpp +33 -0
  547. data/ext/boost/thread/detail/platform.hpp +71 -0
  548. data/ext/boost/thread/exceptions.hpp +109 -0
  549. data/ext/boost/thread/locks.hpp +589 -0
  550. data/ext/boost/thread/mutex.hpp +21 -0
  551. data/ext/boost/thread/once.hpp +29 -0
  552. data/ext/boost/thread/pthread/condition_variable.hpp +184 -0
  553. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +66 -0
  554. data/ext/boost/thread/pthread/mutex.hpp +211 -0
  555. data/ext/boost/thread/pthread/once.hpp +85 -0
  556. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +50 -0
  557. data/ext/boost/thread/pthread/recursive_mutex.hpp +249 -0
  558. data/ext/boost/thread/pthread/thread.hpp +339 -0
  559. data/ext/boost/thread/pthread/thread_data.hpp +102 -0
  560. data/ext/boost/thread/pthread/timespec.hpp +28 -0
  561. data/ext/boost/thread/pthread/tss.hpp +103 -0
  562. data/ext/boost/thread/recursive_mutex.hpp +21 -0
  563. data/ext/boost/thread/thread.hpp +22 -0
  564. data/ext/boost/thread/thread_time.hpp +46 -0
  565. data/ext/boost/thread/tss.hpp +18 -0
  566. data/ext/boost/thread/xtime.hpp +88 -0
  567. data/ext/boost/throw_exception.hpp +46 -0
  568. data/ext/boost/token_functions.hpp +621 -0
  569. data/ext/boost/token_iterator.hpp +128 -0
  570. data/ext/boost/tokenizer.hpp +98 -0
  571. data/ext/boost/type.hpp +18 -0
  572. data/ext/boost/type_traits/add_const.hpp +47 -0
  573. data/ext/boost/type_traits/add_pointer.hpp +72 -0
  574. data/ext/boost/type_traits/add_reference.hpp +89 -0
  575. data/ext/boost/type_traits/alignment_of.hpp +100 -0
  576. data/ext/boost/type_traits/broken_compiler_spec.hpp +117 -0
  577. data/ext/boost/type_traits/composite_traits.hpp +29 -0
  578. data/ext/boost/type_traits/config.hpp +76 -0
  579. data/ext/boost/type_traits/conversion_traits.hpp +17 -0
  580. data/ext/boost/type_traits/detail/bool_trait_def.hpp +173 -0
  581. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +27 -0
  582. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +97 -0
  583. data/ext/boost/type_traits/detail/false_result.hpp +28 -0
  584. data/ext/boost/type_traits/detail/ice_and.hpp +35 -0
  585. data/ext/boost/type_traits/detail/ice_eq.hpp +36 -0
  586. data/ext/boost/type_traits/detail/ice_not.hpp +31 -0
  587. data/ext/boost/type_traits/detail/ice_or.hpp +34 -0
  588. data/ext/boost/type_traits/detail/is_function_ptr_helper.hpp +220 -0
  589. data/ext/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp +817 -0
  590. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +58 -0
  591. data/ext/boost/type_traits/detail/size_t_trait_undef.hpp +16 -0
  592. data/ext/boost/type_traits/detail/template_arity_spec.hpp +31 -0
  593. data/ext/boost/type_traits/detail/type_trait_def.hpp +61 -0
  594. data/ext/boost/type_traits/detail/type_trait_undef.hpp +19 -0
  595. data/ext/boost/type_traits/detail/yes_no_type.hpp +26 -0
  596. data/ext/boost/type_traits/function_traits.hpp +236 -0
  597. data/ext/boost/type_traits/has_nothrow_copy.hpp +39 -0
  598. data/ext/boost/type_traits/has_trivial_copy.hpp +49 -0
  599. data/ext/boost/type_traits/ice.hpp +20 -0
  600. data/ext/boost/type_traits/integral_constant.hpp +53 -0
  601. data/ext/boost/type_traits/intrinsics.hpp +153 -0
  602. data/ext/boost/type_traits/is_abstract.hpp +144 -0
  603. data/ext/boost/type_traits/is_arithmetic.hpp +43 -0
  604. data/ext/boost/type_traits/is_array.hpp +90 -0
  605. data/ext/boost/type_traits/is_class.hpp +128 -0
  606. data/ext/boost/type_traits/is_const.hpp +142 -0
  607. data/ext/boost/type_traits/is_convertible.hpp +418 -0
  608. data/ext/boost/type_traits/is_enum.hpp +180 -0
  609. data/ext/boost/type_traits/is_float.hpp +27 -0
  610. data/ext/boost/type_traits/is_function.hpp +95 -0
  611. data/ext/boost/type_traits/is_integral.hpp +73 -0
  612. data/ext/boost/type_traits/is_member_function_pointer.hpp +134 -0
  613. data/ext/boost/type_traits/is_member_pointer.hpp +114 -0
  614. data/ext/boost/type_traits/is_pod.hpp +135 -0
  615. data/ext/boost/type_traits/is_pointer.hpp +160 -0
  616. data/ext/boost/type_traits/is_reference.hpp +116 -0
  617. data/ext/boost/type_traits/is_same.hpp +103 -0
  618. data/ext/boost/type_traits/is_scalar.hpp +55 -0
  619. data/ext/boost/type_traits/is_union.hpp +49 -0
  620. data/ext/boost/type_traits/is_void.hpp +33 -0
  621. data/ext/boost/type_traits/is_volatile.hpp +131 -0
  622. data/ext/boost/type_traits/remove_const.hpp +78 -0
  623. data/ext/boost/type_traits/remove_cv.hpp +61 -0
  624. data/ext/boost/type_traits/remove_pointer.hpp +43 -0
  625. data/ext/boost/type_traits/remove_reference.hpp +50 -0
  626. data/ext/boost/type_traits/type_with_alignment.hpp +288 -0
  627. data/ext/boost/utility.hpp +19 -0
  628. data/ext/boost/utility/addressof.hpp +58 -0
  629. data/ext/boost/utility/base_from_member.hpp +87 -0
  630. data/ext/boost/utility/compare_pointees.hpp +68 -0
  631. data/ext/boost/utility/enable_if.hpp +119 -0
  632. data/ext/boost/visit_each.hpp +29 -0
  633. data/ext/boost/weak_ptr.hpp +188 -0
  634. data/lib/rake/cplusplus.rb +43 -0
  635. data/lib/rake/extensions.rb +175 -0
  636. data/lib/rake/gempackagetask.rb +99 -0
  637. data/lib/rake/packagetask.rb +186 -0
  638. data/lib/rake/rdoctask.rb +209 -0
  639. data/man/passenger-config.1 +29 -0
  640. data/man/passenger-make-enterprisey.8 +23 -0
  641. data/man/passenger-memory-stats.8 +33 -0
  642. data/man/passenger-status.8 +43 -0
  643. data/man/passenger-stress-test.1 +43 -0
  644. data/misc/copy_boost_headers.rb +102 -0
  645. data/misc/find_owner_pipe_leaks.rb +121 -0
  646. data/misc/render_error_pages.rb +108 -0
  647. data/test/ApplicationPoolServerTest.cpp +74 -0
  648. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +31 -0
  649. data/test/ApplicationPoolTest.cpp +634 -0
  650. data/test/CxxTestMain.cpp +25 -0
  651. data/test/MessageChannelTest.cpp +312 -0
  652. data/test/SpawnManagerTest.cpp +64 -0
  653. data/test/StandardApplicationPoolTest.cpp +25 -0
  654. data/test/UtilsTest.cpp +238 -0
  655. data/test/config.yml.example +21 -0
  656. data/test/integration_tests.rb +791 -0
  657. data/test/ruby/abstract_server_spec.rb +17 -0
  658. data/test/ruby/application_spec.rb +43 -0
  659. data/test/ruby/message_channel_spec.rb +170 -0
  660. data/test/ruby/rack/application_spawner_spec.rb +41 -0
  661. data/test/ruby/rails/application_spawner_spec.rb +148 -0
  662. data/test/ruby/rails/framework_spawner_spec.rb +130 -0
  663. data/test/ruby/rails/minimal_spawner_spec.rb +74 -0
  664. data/test/ruby/rails/spawner_error_handling_spec.rb +52 -0
  665. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +97 -0
  666. data/test/ruby/spawn_manager_spec.rb +189 -0
  667. data/test/ruby/spawn_server_spec.rb +26 -0
  668. data/test/ruby/utils_spec.rb +67 -0
  669. data/test/stub/apache2/httpd.conf.erb +79 -0
  670. data/test/stub/apache2/mime.types +748 -0
  671. data/test/stub/garbage1.dat +0 -0
  672. data/test/stub/garbage2.dat +0 -0
  673. data/test/stub/garbage3.dat +0 -0
  674. data/test/stub/http_request.yml +23 -0
  675. data/test/stub/message_channel.rb +9 -0
  676. data/test/stub/message_channel_2.rb +10 -0
  677. data/test/stub/message_channel_3.rb +17 -0
  678. data/test/stub/minimal-railsapp/README +3 -0
  679. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  680. data/test/stub/minimal-railsapp/config/environment.rb +3 -0
  681. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  682. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +10 -0
  683. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  684. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  685. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +7 -0
  686. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  687. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +17 -0
  688. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  689. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  690. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +8 -0
  691. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +1 -0
  692. data/test/stub/rack/config.ru +4 -0
  693. data/test/stub/rack/public/rack.jpg +0 -0
  694. data/test/stub/rails_apps/foobar/app/controllers/application.rb +12 -0
  695. data/test/stub/rails_apps/foobar/app/controllers/bar_controller_1.rb +5 -0
  696. data/test/stub/rails_apps/foobar/app/controllers/bar_controller_2.rb +5 -0
  697. data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +21 -0
  698. data/test/stub/rails_apps/foobar/app/helpers/application_helper.rb +3 -0
  699. data/test/stub/rails_apps/foobar/config/boot.rb +108 -0
  700. data/test/stub/rails_apps/foobar/config/database.yml +19 -0
  701. data/test/stub/rails_apps/foobar/config/environment.rb +59 -0
  702. data/test/stub/rails_apps/foobar/config/environments/development.rb +17 -0
  703. data/test/stub/rails_apps/foobar/config/environments/production.rb +18 -0
  704. data/test/stub/rails_apps/foobar/config/initializers/inflections.rb +10 -0
  705. data/test/stub/rails_apps/foobar/config/initializers/mime_types.rb +5 -0
  706. data/test/stub/rails_apps/foobar/config/routes.rb +35 -0
  707. data/test/stub/rails_apps/mycook/app/controllers/application.rb +12 -0
  708. data/test/stub/rails_apps/mycook/app/controllers/recipes_controller.rb +5 -0
  709. data/test/stub/rails_apps/mycook/app/controllers/uploads_controller.rb +11 -0
  710. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +55 -0
  711. data/test/stub/rails_apps/mycook/app/helpers/application_helper.rb +3 -0
  712. data/test/stub/rails_apps/mycook/app/views/layouts/default.rhtml +26 -0
  713. data/test/stub/rails_apps/mycook/app/views/recipes/create.rhtml +13 -0
  714. data/test/stub/rails_apps/mycook/app/views/recipes/index.rhtml +3 -0
  715. data/test/stub/rails_apps/mycook/app/views/recipes/new.rhtml +8 -0
  716. data/test/stub/rails_apps/mycook/app/views/uploads/index.rhtml +1 -0
  717. data/test/stub/rails_apps/mycook/app/views/uploads/new.html.erb +8 -0
  718. data/test/stub/rails_apps/mycook/app/views/welcome/cached.rhtml +1 -0
  719. data/test/stub/rails_apps/mycook/app/views/welcome/index.rhtml +20 -0
  720. data/test/stub/rails_apps/mycook/config/boot.rb +108 -0
  721. data/test/stub/rails_apps/mycook/config/database.yml +19 -0
  722. data/test/stub/rails_apps/mycook/config/environment.rb +61 -0
  723. data/test/stub/rails_apps/mycook/config/environments/development.rb +18 -0
  724. data/test/stub/rails_apps/mycook/config/environments/production.rb +19 -0
  725. data/test/stub/rails_apps/mycook/config/initializers/inflections.rb +10 -0
  726. data/test/stub/rails_apps/mycook/config/initializers/mime_types.rb +5 -0
  727. data/test/stub/rails_apps/mycook/config/routes.rb +38 -0
  728. data/test/stub/rails_apps/mycook/log/useless.txt +1 -0
  729. data/test/stub/rails_apps/mycook/public/404.html +30 -0
  730. data/test/stub/rails_apps/mycook/public/422.html +30 -0
  731. data/test/stub/rails_apps/mycook/public/500.html +30 -0
  732. data/test/stub/rails_apps/mycook/public/dispatch.cgi +10 -0
  733. data/test/stub/rails_apps/mycook/public/dispatch.fcgi +24 -0
  734. data/test/stub/rails_apps/mycook/public/dispatch.rb +10 -0
  735. data/test/stub/rails_apps/mycook/public/favicon.ico +0 -0
  736. data/test/stub/rails_apps/mycook/public/images/angrywizard.gif +0 -0
  737. data/test/stub/rails_apps/mycook/public/images/cookbook.gif +0 -0
  738. data/test/stub/rails_apps/mycook/public/images/header.png +0 -0
  739. data/test/stub/rails_apps/mycook/public/images/rails.png +0 -0
  740. data/test/stub/rails_apps/mycook/public/javascripts/application.js +2 -0
  741. data/test/stub/rails_apps/mycook/public/javascripts/controls.js +963 -0
  742. data/test/stub/rails_apps/mycook/public/javascripts/dragdrop.js +972 -0
  743. data/test/stub/rails_apps/mycook/public/javascripts/effects.js +1120 -0
  744. data/test/stub/rails_apps/mycook/public/javascripts/prototype.js +4225 -0
  745. data/test/stub/rails_apps/mycook/public/robots.txt +5 -0
  746. data/test/stub/rails_apps/mycook/public/uploads.html +26 -0
  747. data/test/stub/rails_apps/mycook/public/welcome/cached.html +26 -0
  748. data/test/stub/rails_apps/mycook/tmp/cache/useless.txt +1 -0
  749. data/test/stub/rails_apps/mycook/tmp/pids/useless.txt +1 -0
  750. data/test/stub/rails_apps/mycook/tmp/sessions/useless.txt +1 -0
  751. data/test/stub/rails_apps/mycook/tmp/sockets/useless.txt +1 -0
  752. data/test/stub/railsapp/app/controllers/application.rb +12 -0
  753. data/test/stub/railsapp/app/controllers/bar_controller_1.rb +5 -0
  754. data/test/stub/railsapp/app/controllers/bar_controller_2.rb +5 -0
  755. data/test/stub/railsapp/app/controllers/foo_controller.rb +9 -0
  756. data/test/stub/railsapp/app/helpers/application_helper.rb +3 -0
  757. data/test/stub/railsapp/config/boot.rb +108 -0
  758. data/test/stub/railsapp/config/database.yml +19 -0
  759. data/test/stub/railsapp/config/environment.rb +59 -0
  760. data/test/stub/railsapp/config/environments/development.rb +18 -0
  761. data/test/stub/railsapp/config/environments/production.rb +19 -0
  762. data/test/stub/railsapp/config/initializers/inflections.rb +10 -0
  763. data/test/stub/railsapp/config/initializers/mime_types.rb +5 -0
  764. data/test/stub/railsapp/config/routes.rb +35 -0
  765. data/test/stub/railsapp/public/useless.txt +1 -0
  766. data/test/stub/railsapp2/app/controllers/application.rb +12 -0
  767. data/test/stub/railsapp2/app/controllers/foo_controller.rb +5 -0
  768. data/test/stub/railsapp2/app/helpers/application_helper.rb +3 -0
  769. data/test/stub/railsapp2/config/boot.rb +108 -0
  770. data/test/stub/railsapp2/config/database.yml +19 -0
  771. data/test/stub/railsapp2/config/environment.rb +59 -0
  772. data/test/stub/railsapp2/config/environments/development.rb +18 -0
  773. data/test/stub/railsapp2/config/environments/production.rb +19 -0
  774. data/test/stub/railsapp2/config/initializers/inflections.rb +10 -0
  775. data/test/stub/railsapp2/config/initializers/mime_types.rb +5 -0
  776. data/test/stub/railsapp2/config/routes.rb +35 -0
  777. data/test/stub/railsapp2/public/useless.txt +1 -0
  778. data/test/stub/spawn_server.rb +20 -0
  779. data/test/stub/upload_data.txt +494 -0
  780. data/test/stub/vendor_rails/minimal/README +1 -0
  781. data/test/stub/vendor_rails/minimal/actionmailer/lib/action_mailer.rb +0 -0
  782. data/test/stub/vendor_rails/minimal/actionpack/lib/action_controller.rb +19 -0
  783. data/test/stub/vendor_rails/minimal/actionpack/lib/action_pack.rb +0 -0
  784. data/test/stub/vendor_rails/minimal/actionpack/lib/action_view.rb +0 -0
  785. data/test/stub/vendor_rails/minimal/activerecord/lib/active_record.rb +7 -0
  786. data/test/stub/vendor_rails/minimal/activeresource/lib/active_resource.rb +0 -0
  787. data/test/stub/vendor_rails/minimal/activesupport/lib/active_support.rb +17 -0
  788. data/test/stub/vendor_rails/minimal/activesupport/lib/active_support/whiny_nil.rb +0 -0
  789. data/test/stub/vendor_rails/minimal/railties/lib/dispatcher.rb +0 -0
  790. data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +52 -0
  791. data/test/stub/vendor_rails/minimal/railties/lib/ruby_version_check.rb +1 -0
  792. data/test/stub/wsgi/passenger_wsgi.py +3 -0
  793. data/test/stub/wsgi/public/wsgi-snake.jpg +0 -0
  794. data/test/stub/zsfa/header.png +0 -0
  795. data/test/stub/zsfa/index.html +14 -0
  796. data/test/stub/zsfa/zsfa.png +0 -0
  797. data/test/support/apache2_controller.rb +246 -0
  798. data/test/support/config.rb +13 -0
  799. data/test/support/multipart.rb +62 -0
  800. data/test/support/run_rspec_tests.rb +10 -0
  801. data/test/support/test_helper.rb +94 -0
  802. data/test/support/tut.h +1234 -0
  803. data/test/support/tut_reporter.h +256 -0
  804. data/test/support/valgrind.h +2539 -0
  805. metadata +1342 -0
@@ -0,0 +1,197 @@
1
+ Security of user switching support in Passenger
2
+ ===============================================
3
+
4
+ Problem description
5
+ -------------------
6
+ TIP: It is strongly recommended that you first read our
7
+ link:Architectural%20overview.html[Architectural Overview].
8
+
9
+ A straightforward implementation of Passenger will spawn Rails applications in
10
+ the same user context as Apache itself. On server machines which host multiple
11
+ websites for multiple users, this may not be desired. All Rails applications
12
+ spawned by Passenger will be able to read and write to all directories that the
13
+ web server can. So for example, Joe's Rails applications could read Jane's
14
+ Rails application's 'database.yml' or delete her application files. This is
15
+ also a problem that typically plagues PHP web hosts.
16
+
17
+ There are multiple ways to solve this problem. The goal of this document is to
18
+ inform the reader about the solutions have we have analyzed, so that
19
+ Passenger's security may be peer reviewed.
20
+
21
+
22
+ Analysis of possible solutions
23
+ ------------------------------
24
+ It seems that the only way to solve this problem on Unix, is to run each Rails
25
+ application server as its owner's user and group. Passenger can make use of
26
+ one of the following methods to implement this:
27
+
28
+ 1. Apache (and thus Passenger) must already be running as root.
29
+ 2. Using Apache's suEXEC.
30
+ 3. A setuid root wrapper application must exist, to allow non-root processes
31
+ to obtain root privileges (or at least, the privilege to switch user).
32
+ 4. For each user $X that Passenger will need to switch to, there must exist
33
+ a setuid $X wrapper application.
34
+ 5. Using 'su'.
35
+ 6. Using 'sudo'.
36
+
37
+ Let us take a look at each method in detail.
38
+
39
+ [[apache_root]]
40
+ Apache must already be running as root
41
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
+ First, let us take a look at the typical Apache setup, in which Apache is bound
43
+ to port 80, and uses the prefork MPM. Binding to any port lower than 1024
44
+ requires root privileges, so Apache is typically run as root. This poses an
45
+ unacceptable security risk, so Apache's prefork MPM will, upon receiving an
46
+ HTTP request, spawn a child process with the privileges of a normal user,
47
+ typically 'www-data' or 'nobody'.
48
+ See http://httpd.apache.org/docs/2.2/mod/prefork.html[the documentation for the
49
+ prefork MPM] - in particular the ``User'' and ``Group'' directives - for details.
50
+ The process which is responsible for spawning child processes (also called the
51
+ control process) is run as root. This is also true for
52
+ http://httpd.apache.org/docs/2.2/mod/worker.html[the worker MPM].
53
+
54
+ Since Passenger has access to the control process, in the typical Apache setup,
55
+ Passenger can already launch Rails applications as a different user. But now we
56
+ have to ask this question:
57
+
58
+ =================================
59
+ If Apache is not running as root, are there still any Passenger users who
60
+ want to run Rails applications as different users?
61
+ =================================
62
+
63
+ If the answer is yes, then we cannot use this method.
64
+
65
+ The advantage of this method is that setting up Apache to run as root is
66
+ incredibly easy, and requires no new framework to be written. However, testing
67
+ this method in automated unit tests will require running the unit test suit as
68
+ root.
69
+
70
+ Using Apache's suEXEC
71
+ ~~~~~~~~~~~~~~~~~~~~~
72
+ Apache's http://httpd.apache.org/docs/2.0/suexec.html[suEXEC] allows one to
73
+ run CGI processes as different users. But it seems that suEXEC can only be
74
+ used for CGI, and is not a general-purpose mechanism. The
75
+ http://alain.knaff.lu/howto/PhpSuexec/[PHP-suEXEC] software allows one to run
76
+ PHP applications via suEXEC, but it requires patching suEXEC. If Passenger is
77
+ to use suEXEC, then it is likely that we'll have to patch suEXEC. The suEXEC
78
+ website strongly discourages patching.
79
+
80
+ Using a setuid root wrapper application
81
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82
+ If we use this method, we must be extremely careful. It must not be possible
83
+ for arbitrary processes to gain root privileges. We want Passenger, and only
84
+ Passenger, to be able to gain root privileges.
85
+
86
+ There are multiple ways to implement this security. The first one is to use
87
+ a password file, which only Apache and the wrapper can read, through
88
+ the use of proper file permissions. The password file must never be world
89
+ readable or writable.
90
+
91
+ It works as follows:
92
+
93
+ 1. Passenger runs the wrapper.
94
+ 2. Passenger passes the content of the password file to the wrapper, via
95
+ an anonymous pipe (or some other anonymous channel, that no other
96
+ processes can access).
97
+ 3. The wrapper checks whether the passed content is the same as what is in
98
+ the password file. If it is, then it is proven that whatever application
99
+ ran the wrapper has read access to the password file, and thus is authorized
100
+ to use the wrapper.
101
+
102
+ An obvious problem that arises is: how does the wrapper locate its own password
103
+ file? We obviously do not want to be able to specify the password filename as
104
+ an argument to the wrapper: that would defeat the point of the password file.
105
+ The solution is that the filename is to be hardcoded into the binary during
106
+ compile time.
107
+
108
+ Another way to implement security is to use a whitelist of users that are
109
+ allowed to use the wrapper. The wrapper can then check whether the calling
110
+ process's user is in the whitelist.
111
+
112
+ Writing a wrapper is not too hard. Furthermore, unit tests do not have to be
113
+ run as root, in contrast to the run-Apache-as-root method.
114
+
115
+ [[setuid_root]]
116
+ Using a setuid $X wrapper application
117
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
+ A setuid $X wrapper will work in a fashion similar to the setuid root wrapper,
119
+ i.e. it will use a password file for authorization.
120
+
121
+ Passenger does not spawn Rails applications itself, but does so via the spawn
122
+ server. This spawn server is also responsible for preloading the Rails
123
+ framework and the Rails application code, in order to speed up the spawning
124
+ of Rails applications. See the design document of the spawn server for details.
125
+ The spawn server never calls `exec()`: doing so will make preloading useless.
126
+ If Passenger is to use a setuid $X wrapper, then it must start the spawn
127
+ server via the wrapper. The spawn server itself cannot use the wrapper.
128
+
129
+ However, doing so will make preloading less efficient. Passenger will be forced
130
+ to run a spawn server for each user. The different spawn servers do not share
131
+ memory with each other, so a lot of memory is wasted compared to the other
132
+ methods.
133
+
134
+ Implementing this will also take more work. One has to create a different
135
+ wrapper for each user, and to install it.
136
+
137
+ Using 'su'
138
+ ~~~~~~~~~~
139
+ The standard Unix 'su' tool asks for the root password. It's a bad idea for
140
+ Apache to know the root password, so using 'su' is not a viable alternative.
141
+
142
+ Using 'sudo'
143
+ ~~~~~~~~~~~~
144
+ It might be possible to use the 'sudo' utility. sudo can be configured in
145
+ such a way that the user Apache runs as can use sudo without having to enter a
146
+ password.
147
+
148
+ However, Passenger uses an anonymous communication channel (an unnamed Unix
149
+ socket) to communicate with the spawn server. sudo seems to close all file
150
+ descriptors before executing an application, so Passenger will have to
151
+ communicate with the spawn server via a non-anonymous channel, such as a named
152
+ Unix socket. Because other processes can access this channel, it can introduce
153
+ potential security problems. Note that passing information via program arguments
154
+ is not secure: it is possible to view that information with tools like 'ps',
155
+ or (on Linux) by reading the file `/proc/$PID/cmdline`.
156
+
157
+ So it seems 'sudo' is not a viable alternative.
158
+
159
+ Common security issues
160
+ ~~~~~~~~~~~~~~~~~~~~~~
161
+ Whatever method Passenger will use, the following security principles must be
162
+ honored:
163
+
164
+ - Rails applications must never be run as root.
165
+
166
+ It might also be worthy to look into suEXEC's security model for inspiration.
167
+
168
+ Also, the following questions remain:
169
+
170
+ - Is there a need for a user whitelist/blacklist? That is, is there a need for
171
+ the ability to restrict the set of users that Passenger can switch to?
172
+
173
+
174
+ Chosen solution
175
+ ---------------
176
+ Running Apache as root and writing a setuid root wrapper are the main
177
+ contestants. The former is preferred, because it's easier to implement.
178
+
179
+ We have had some conversations with people on the IRC channel #rubyonrails.
180
+ Among those people, nobody has ever run Apache as non-root. Because of this
181
+ we have chosen to implement the <<apache_root,Running Apache as root>>
182
+ solution, until a significant number of users request us to implement the
183
+ <<setuid_root,setuid root wrapper>> solution.
184
+
185
+ Please read link:rdoc/index.html[the Ruby API documentation] -- in particular
186
+ that of the 'ApplicationSpawner' class -- for implementation details. But to
187
+ make a long story short: it will switch to the owner of the file
188
+ 'config/environment.rb'. User whitelisting/blacklisting is currently not
189
+ implemented. We rely on the system administrator to set the correct owner
190
+ on that file.
191
+
192
+ We have also not implemented suEXEC's security model. suEXEC's model is quite
193
+ paranoid, and although paranoia is good to a certain extend, it can be in the
194
+ way of usability while proving little extra security. We are not entirely
195
+ convinced that implementing suEXEC's full security model will provide
196
+ significant benefits, but if you have good reasons to think otherwise, please
197
+ feel free to discuss it with us.
@@ -0,0 +1,2237 @@
1
+ = Phusion Passenger users guide =
2
+
3
+ image:images/phusion_banner.png[link="http://www.phusion.nl/"]
4
+
5
+ Phusion Passenger is an Apache module, which makes deploying Ruby and Ruby on
6
+ Rails applications on Apache a breeze. It follows the usual Ruby on Rails
7
+ conventions, such as "Don't-Repeat-Yourself" and ease of setup, while at the
8
+ same time providing enough flexibility.
9
+
10
+ This users guide will teach you:
11
+
12
+ - How to install Phusion Passenger.
13
+ - How to configure Phusion Passenger.
14
+ - How to deploy a Ruby on Rails application.
15
+ - How to deploy a link:http://rack.rubyforge.org/[Rack]-based Ruby application.
16
+ - How to solve common problems.
17
+
18
+ This guide assumes that the reader is somewhat familiar with Apache and with
19
+ using the commandline.
20
+
21
+
22
+ == Supported operating systems ==
23
+
24
+ Phusion Passenger works on any POSIX-compliant operating system. In other
25
+ words: practically any operating system on earth, except Microsoft Windows.
26
+
27
+ Phusion Passenger has been tested on:
28
+
29
+ - Ubuntu Linux 6.06 (x86)
30
+ - Ubuntu Linux 7.10 (x86)
31
+ - Ubuntu Linux 8.04 (x86)
32
+ - Debian Sarge (x86)
33
+ - Debian Etch (x86)
34
+ - Debian Lenny/Sid (x86)
35
+ - CentOS 5 (x86)
36
+ - Red Hat Enterprise Linux 5 (x86)
37
+ - Gentoo, March 14 2008 (AMD64)
38
+ - FreeBSD 6.1-RELEASE (x86)
39
+ - MacOS X Tiger (x86)
40
+ - MacOS X Leopard (x86)
41
+
42
+ Other operating systems have not been tested, but Phusion Passenger will probably
43
+ work fine on them. Please
44
+ link:http://code.google.com/p/phusion-passenger/issues/list[report a bug]
45
+ or
46
+ link:http://groups.google.com/group/phusion-passenger[join our discussion list]
47
+ if it doesn't.
48
+
49
+
50
+ == Installing Phusion Passenger ==
51
+
52
+ === Generic installation instructions ===
53
+
54
+ [[install_passenger]]
55
+ ==== Overview of download and installation methods ====
56
+
57
+ There are two ways to install Phusion Passenger:
58
+
59
+ 1. By installing the Phusion Passenger gem, as instructed on the
60
+ link:http://www.modrails.com/install.html[``Install'' page on the Phusion
61
+ Passenger website].
62
+ 2. By downloading a native Linux package (e.g. Debian package) from the
63
+ Phusion Passenger website.
64
+ 3. By downloading the source tarball from the Phusion Passenger website
65
+ ('passenger-x.x.x.tar.gz').
66
+
67
+ In our opinion, installing the gem or the native package is easiest.
68
+
69
+ Phusion Passenger provides an easy-to-use installer for installing the Phusion
70
+ Passenger Apache module ('mod_passenger').
71
+
72
+ TIP: You might have to run the installation commands in the following sections
73
+ as 'root'. If the installer fails because of permission errors, it will tell
74
+ you.
75
+
76
+ [[specifying_correct_apache_install]]
77
+ ==== Specifying the correct Apache installation ====
78
+
79
+ NOTE: You can skip this section if you've installed Phusion Passenger via a
80
+ native Linux package, because no compilation is necessary.
81
+
82
+ If your system has multiple Apache installations (this is likely the case on
83
+ MacOS X), then you will need to tell the Phusion Passenger installer which one
84
+ to use. If you only have one Apache installation (the case on most Linux
85
+ systems), then you can skip this section because Phusion Passenger will
86
+ automatically detect it.
87
+
88
+ Every Apache installation has its own `apxs` program. You will need to tell
89
+ Phusion Passenger the location of this program, by specifying the `APXS2`
90
+ environment variable. Suppose that you want to use the Apache installation in
91
+ '/opt/apache2'. Then, assuming that the corresponding `apxs` program is located
92
+ '/opt/apache2/bin/apxs', type:
93
+ ----------------------------------
94
+ export APXS2=/opt/apache2/bin/apxs
95
+ ----------------------------------
96
+
97
+ NOTE: On some systems, the `apxs` program might be called `apxs2`, and it might
98
+ be located in the `sbin` folder instead of the `bin` folder.
99
+
100
+ [[specifying_ruby_installation]]
101
+ ==== Specifying the correct Ruby installation ====
102
+
103
+ NOTE: You can skip this section if you've installed Phusion Passenger via a
104
+ native Linux package, because no compilation is necessary.
105
+
106
+ If your system has multiple Ruby installations (this is likely the case on
107
+ MacOS X), then you will need to tell the Phusion Passenger installer which one
108
+ to use. If you only have one Ruby installation (the case on most Linux systems),
109
+ then you can skip this section because Phusion Passenger will automatically detect it.
110
+
111
+ To specify the Ruby installation, prepend your Ruby installation's `bin`
112
+ directory to the `PATH` environment variable. For example, if you have the
113
+ following Ruby installations:
114
+
115
+ - /usr/bin/ruby
116
+ - /opt/myruby/bin/ruby
117
+
118
+ and you want to use the latter, then type:
119
+
120
+ ----------------------------------
121
+ export PATH=/opt/myruby/bin:$PATH
122
+ ----------------------------------
123
+
124
+
125
+ ==== Installing via the gem ====
126
+
127
+ Please install the gem and then run the Phusion Passenger installer, by typing the
128
+ following commands:
129
+ ------------------------------------------------------
130
+ gem install passenger-x.x.x.gem
131
+ passenger-install-apache2-module
132
+ ------------------------------------------------------
133
+ Please follow the instructions given by the installer.
134
+
135
+ ==== Installing via a native Linux package ====
136
+
137
+ Please install the native Linux package, e.g.:
138
+ ------------------------------------------------------
139
+ gdebi passenger_x.x.x-i386.deb
140
+ ------------------------------------------------------
141
+
142
+ Next, you'll need to configure Apache. Run the "installer", as it will tell you
143
+ the correct configuration options for Apache:
144
+ ------------------------------------------------------
145
+ passenger-install-apache2-module
146
+ ------------------------------------------------------
147
+
148
+ NOTE: The installer doesn't actually install anything because it will automatically
149
+ detect that Phusion Passenger has already been installed. The only thing the
150
+ installer will do in this case, is showing the correct Apache configurations.
151
+
152
+ ==== Installing via the source tarball ====
153
+
154
+ Extract the tarball to whatever location you prefer. The Phusion Passenger files
155
+ are to reside in that location permanently. For example, if you would like
156
+ Phusion Passenger to reside in `/opt/passenger-x.x.x`:
157
+ ------------------------------------------------------
158
+ cd /opt
159
+ tar xzvf ~/YourDownloadsFolder/passenger-x.x.x.tar.gz
160
+ ------------------------------------------------------
161
+
162
+ Next, run the included installer:
163
+ ------------------------------------------------------
164
+ /opt/passenger-x.x.x/bin/passenger-install-apache2-module
165
+ ------------------------------------------------------
166
+ Please follow the instructions given by the installer.
167
+
168
+ IMPORTANT: Please do not remove the 'passenger-x.x.x' folder after
169
+ installation. Furthermore, the 'passenger-x.x.x' folder must be accessible by Apache.
170
+
171
+
172
+ === Operating system-specific instructions and information ===
173
+
174
+ ==== MacOS X ====
175
+
176
+ Ben Ruebenstein has written an excellent
177
+ link:http://benr75.com/articles/2008/04/12/setup-mod_rails-phusion-mac-os-x-leopard[tutorial
178
+ on installing Phusion Passenger on OS X].
179
+
180
+ ==== Ubuntu Linux ====
181
+
182
+ Ben Hughes has written an link:http://www.railsgarden.com/2008/04/12/configurating-passenger-mod_rails-on-slicehost-with-ubuntu-710/[article on installing Phusion Passenger on Ubuntu].
183
+
184
+
185
+ == Deploying a Ruby on Rails application ==
186
+
187
+ Suppose you have a Ruby on Rails application in '/webapps/mycook', and you own
188
+ the domain 'www.mycook.com'. You can either deploy your application to the
189
+ virtual host's root (i.e. the application will be accessible from the root URL,
190
+ 'http://www.mycook.com/'), or in a sub URI (i.e. the application will be
191
+ accessible from a sub URL, such as 'http://www.mycook.com/railsapplication').
192
+
193
+ NOTE: The default `RAILS_ENV` environment in which deployed Rails applications
194
+ are run, is ``production''. You can change this by changing the
195
+ <<rails_env,'RailsEnv'>> configuration option.
196
+
197
+ === Deploying to a virtual host's root ===
198
+
199
+ Add a virtual host entry to your Apache configuration file. The virtual host's
200
+ document root must point to your Ruby on Rails application's 'public' folder.
201
+ For example:
202
+ -------------------------------------------
203
+ <VirtualHost *:80>
204
+ ServerName www.mycook.com
205
+ DocumentRoot /webapps/mycook/public
206
+ </VirtualHost>
207
+ -------------------------------------------
208
+ Then restart Apache. The application has now been deployed.
209
+
210
+ [[deploying_rails_to_sub_uri]]
211
+ === Deploying to a sub URI ===
212
+
213
+ Suppose that you already have a virtual host:
214
+
215
+ -------------------------------------------
216
+ <VirtualHost *:80>
217
+ ServerName www.phusion.nl
218
+ DocumentRoot /websites/phusion
219
+ </VirtualHost>
220
+ -------------------------------------------
221
+
222
+ And you want your Ruby on Rails application to be accessible from the URL
223
+ 'http://www.phusion.nl/rails'.
224
+
225
+ To do this, make a symlink from your Ruby on Rails application's 'public'
226
+ folder to a directory in the document root. For example:
227
+ -------------------------------------------
228
+ ln -s /webapps/mycook/public /websites/phusion/rails
229
+ -------------------------------------------
230
+
231
+ Next, add a <<RailsBaseURI,RailsBaseURI>> option to the virtual host configuration:
232
+ -------------------------------------------
233
+ <VirtualHost *:80>
234
+ ServerName www.phusion.nl
235
+ DocumentRoot /websites/phusion
236
+ RailsBaseURI /rails # This line has been added.
237
+ </VirtualHost>
238
+ -------------------------------------------
239
+ Then restart Apache. The application has now been deployed.
240
+
241
+ [TIP]
242
+ ======================================
243
+ You can deploy multiple Rails applications under a virtual host, by specifying
244
+ <<RailsBaseURI,RailsBaseURI>> multiple times. For example:
245
+ ---------------------------------
246
+ <VirtualHost *:80>
247
+ ....
248
+ RailsBaseURI /app1
249
+ RailsBaseURI /app2
250
+ RailsBaseURI /app3
251
+ </VirtualHost>
252
+ ---------------------------------
253
+ ======================================
254
+
255
+ === Redeploying (restarting the Ruby on Rails application) ===
256
+
257
+ Deploying a new version of a Ruby on Rails application is as simple as
258
+ re-uploading the application files, and restarting the application.
259
+
260
+ There are two ways to restart the application:
261
+
262
+ 1. By restarting Apache.
263
+ 2. By creating or modifying the file 'tmp/restart.txt' in the Rails
264
+ application's root folder. Phusion Passenger will automatically
265
+ restart the application.
266
+
267
+ For example, to restart our example MyCook application, we type this in the
268
+ command line:
269
+ -------------------------------------------
270
+ touch /webapps/mycook/tmp/restart.txt
271
+ -------------------------------------------
272
+
273
+ === Migrations ===
274
+
275
+ Phusion Passenger is not related to Ruby on Rails migrations in any way. To
276
+ run migrations on your deployment server, please login to your deployment
277
+ server (e.g. with 'ssh') and type `rake db:migrate RAILS_ENV=production` in
278
+ a shell console, just like one would normally run migrations.
279
+
280
+ === Capistrano integration ===
281
+
282
+ See <<capistrano,Capistrano recipe>>.
283
+
284
+
285
+ == Deploying a Rack-based Ruby application ==
286
+
287
+ Phusion Passenger supports arbitrary Ruby web applications that follow the
288
+ link:http://rack.rubyforge.org/[Rack] interface.
289
+
290
+ Phusion Passenger assumes that Rack application directories have a certain layout.
291
+ Suppose that you have a Rack application in '/webapps/rackapp'. Then that
292
+ folder must contain at least three entries:
293
+
294
+ - 'config.ru', a Rackup file for starting the Rack application. This file must contain
295
+ the complete logic for initializing the application.
296
+ - 'public/', a folder containing public static web assets, like images and stylesheets.
297
+ - 'tmp/', used for 'restart.txt' (our application restart mechanism). This will
298
+ be explained in a following subsection.
299
+
300
+ So '/webapps/rackapp' must, at minimum, look like this:
301
+ ----------------------
302
+ /webapps/rackapp
303
+ |
304
+ +-- config.ru
305
+ |
306
+ +-- public/
307
+ |
308
+ +-- tmp/
309
+ ----------------------
310
+
311
+ Suppose you own the domain 'www.rackapp.com'. You can either deploy your application
312
+ to the virtual host's root (i.e. the application will be accessible from the root URL,
313
+ 'http://www.rackapp.com/'), or in a sub URI (i.e. the application will be
314
+ accessible from a sub URL, such as 'http://www.rackapp.com/rackapp').
315
+
316
+ NOTE: The default `RACK_ENV` environment in which deployed Rack applications
317
+ are run, is ``production''. You can change this by changing the
318
+ <<rack_env,'RackEnv'>> configuration option.
319
+
320
+ === Tutorial/example: writing and deploying a Hello World Rack application ===
321
+
322
+ First we create a Phusion Passenger-compliant Rack directory structure:
323
+
324
+ -------------------------------------------
325
+ $ mkdir /webapps/rack_example
326
+ $ mkdir /webapps/rack_example/public
327
+ $ mkdir /webapps/rack_example/tmp
328
+ -------------------------------------------
329
+
330
+ Next, we write a minimal "hello world" Rack application:
331
+
332
+ -------------------------------------------
333
+ $ cd /webapps/rack_example
334
+ $ some_awesome_editor config.ru
335
+ ...type in some source code...
336
+ $ cat config.ru
337
+ app = proc do |env|
338
+ return [200, { "Content-Type" => "text/html" }, "hello <b>world</b>"]
339
+ end
340
+ run app
341
+ -------------------------------------------
342
+
343
+ Finally, we deploy it by adding the following configuration options to
344
+ the Apache configuration file:
345
+
346
+ -------------------------------------------
347
+ <VirtualHost *:80>
348
+ ServerName www.rackexample.com
349
+ DocumentRoot /webapps/rack_example/public
350
+ </VirtualHost>
351
+ -------------------------------------------
352
+
353
+ And we're done! After an Apache restart, the above Rack application will be available
354
+ under the URL 'http://www.rackexample.com/'.
355
+
356
+ === Deploying to a virtual host's root ===
357
+
358
+ Add a virtual host entry to your Apache configuration file. The virtual host's
359
+ document root must point to your Rack application's 'public' folder.
360
+ For example:
361
+ -------------------------------------------
362
+ <VirtualHost *:80>
363
+ ServerName www.rackapp.com
364
+ DocumentRoot /webapps/rackapp/public
365
+ </VirtualHost>
366
+ -------------------------------------------
367
+ Then restart Apache. The application has now been deployed.
368
+
369
+ [[deploying_rack_to_sub_uri]]
370
+ === Deploying to a sub URI ===
371
+
372
+ Suppose that you already have a virtual host:
373
+
374
+ -------------------------------------------
375
+ <VirtualHost *:80>
376
+ ServerName www.phusion.nl
377
+ DocumentRoot /websites/phusion
378
+ </VirtualHost>
379
+ -------------------------------------------
380
+
381
+ And you want your Rack application to be accessible from the URL
382
+ 'http://www.phusion.nl/rack'.
383
+
384
+ To do this, make a symlink from your Rack application's 'public'
385
+ folder to a directory in the document root. For example:
386
+ -------------------------------------------
387
+ ln -s /webapps/rackapp/public /websites/phusion/rack
388
+ -------------------------------------------
389
+
390
+ Next, add a <<RackBaseURI,RackBaseURI>> option to the virtual host configuration:
391
+ -------------------------------------------
392
+ <VirtualHost *:80>
393
+ ServerName www.phusion.nl
394
+ DocumentRoot /websites/phusion
395
+ RackBaseURI /rack # This line has been added.
396
+ </VirtualHost>
397
+ -------------------------------------------
398
+ Then restart Apache. The application has now been deployed.
399
+
400
+ [TIP]
401
+ ======================================
402
+ You can deploy multiple Rack applications under a virtual host, by specifying
403
+ <<RackBaseURI,RackBaseURI>> multiple times. For example:
404
+ ---------------------------------
405
+ <VirtualHost *:80>
406
+ ....
407
+ RackBaseURI /app1
408
+ RackBaseURI /app2
409
+ RackBaseURI /app3
410
+ </VirtualHost>
411
+ ---------------------------------
412
+ ======================================
413
+
414
+ === Redeploying (restarting the Rack application) ===
415
+
416
+ Deploying a new version of a Rack application is as simple as
417
+ re-uploading the application files, and restarting the application.
418
+
419
+ There are two ways to restart the application:
420
+
421
+ 1. By restarting Apache.
422
+ 2. By creating or modifying the file 'tmp/restart.txt' in the Rack
423
+ application's root folder. Phusion Passenger will automatically restart the
424
+ application.
425
+
426
+ For example, to restart our example application, we type this in the
427
+ command line:
428
+ -------------------------------------------
429
+ touch /webapps/rackapp/tmp/restart.txt
430
+ -------------------------------------------
431
+
432
+ === Rackup specifications for various web frameworks ===
433
+
434
+ This subsection shows example 'config.ru' files for various web frameworks.
435
+
436
+ ==== Camping ====
437
+ ------------------------------------------------------
438
+ require 'rubygems'
439
+ require 'rack'
440
+ require 'camping'
441
+
442
+ ##### Begin Camping application
443
+ Camping.goes :Blog
444
+
445
+ ...your application code here...
446
+ ##### End Camping application
447
+
448
+ run Rack::Adapter::Camping.new(Blog)
449
+ ------------------------------------------------------
450
+
451
+ For Camping versions 2.0 and up, using `run Blog` as the final line will do.
452
+
453
+ ==== Halcyon ====
454
+ ------------------------------------------------------
455
+ require 'rubygems'
456
+ require 'halcyon'
457
+ $LOAD_PATH.unshift(Halcyon.root / 'lib')
458
+ Halcyon::Runner.load_config Halcyon.root/'config'/'config.yml'
459
+ run Halcyon::Runner.new
460
+ ------------------------------------------------------
461
+
462
+ ==== Mack ====
463
+ ------------------------------------------------------
464
+ ENV["MACK_ENV"] = ENV["RACK_ENV"]
465
+ load("Rakefile")
466
+ require 'rubygems'
467
+ require 'mack'
468
+ run Mack::Utils::Server.build_app
469
+ ------------------------------------------------------
470
+
471
+ ==== Merb ====
472
+ ------------------------------------------------------
473
+ require 'rubygems'
474
+ require 'merb-core'
475
+
476
+ Merb::Config.setup(
477
+ :merb_root => File.expand_path(File.dirname(__FILE__)),
478
+ :environment => ENV['RACK_ENV']
479
+ )
480
+ Merb.environment = Merb::Config[:environment]
481
+ Merb.root = Merb::Config[:merb_root]
482
+ Merb::BootLoader.run
483
+
484
+ run Merb::Rack::Application.new
485
+ ------------------------------------------------------
486
+
487
+ ==== Ramaze ====
488
+ ------------------------------------------------------
489
+ require "start"
490
+ Ramaze.trait[:essentials].delete Ramaze::Adapter
491
+ Ramaze.start :force => true
492
+ run Ramaze::Adapter::Base
493
+ ------------------------------------------------------
494
+
495
+ ==== Sinatra ====
496
+ ------------------------------------------------------
497
+ require 'rubygems'
498
+ require 'sinatra'
499
+
500
+ root_dir = File.dirname(__FILE__)
501
+
502
+ Sinatra::Application.default_options.merge!(
503
+ :views => File.join(root_dir, 'views'),
504
+ :app_file => File.join(root_dir, 'app.rb'),
505
+ :run => false,
506
+ :env => ENV['RACK_ENV'].to_sym
507
+ )
508
+
509
+ run Sinatra.application
510
+ ------------------------------------------------------
511
+
512
+
513
+ == Configuring Phusion Passenger ==
514
+
515
+ After installation, Phusion Passenger does not need any further configurations.
516
+ Nevertheless, the system administrator may be interested in changing
517
+ Phusion Passenger's behavior. Phusion Passenger's Apache module supports the
518
+ following configuration options:
519
+
520
+ === PassengerRoot <directory> ===
521
+ The location to the Phusion Passenger root directory. This configuration option
522
+ is essential to Phusion Passenger. The correct value is given by the installer,
523
+ and should usually not be changed manually.
524
+
525
+ This required option may only occur once, in the global server configuration.
526
+
527
+ === PassengerLogLevel <integer> ===
528
+ This option allows one to specify how much information Phusion Passenger should
529
+ write to the Apache error log file. A higher log level value means that more
530
+ information will be logged.
531
+
532
+ Possible values are:
533
+
534
+ - '0': Show only errors and warnings.
535
+ - '1': Show the most important debugging information. This might be useful for
536
+ system administrators who are trying to figure out the cause of a
537
+ problem.
538
+ - '2': Show more debugging information. This is typically only useful for developers.
539
+ - '3': Show even more debugging information.
540
+
541
+ This option may only occur once, in the global server configuration.
542
+ The default is '0'.
543
+
544
+ [[PassengerRuby]]
545
+ === PassengerRuby <filename> ===
546
+ This option allows one to specify the Ruby interpreter to use.
547
+
548
+ This option may only occur once, in the global server configuration.
549
+ The default is 'ruby'.
550
+
551
+ [[PassengerAppRoot]]
552
+ === PassengerAppRoot <path/to/root> ===
553
+ By default, Phusion Passenger assumes that the application's root directory
554
+ is the parent directory of the 'public' directory. This option allows one to
555
+ specify the application's root independently from the DocumentRoot, which
556
+ is useful if the 'public' directory lives in a non-standard place.
557
+
558
+ This option may occur in the following places:
559
+
560
+ * In the global server configuration.
561
+ * In a virtual host configuration block.
562
+ * In a `<Directory>` or `<Location>` block.
563
+ * In '.htaccess', if `AllowOverride Options` is on.
564
+
565
+ In each place, it may be specified at most once.
566
+
567
+ Example:
568
+
569
+ -----------------------------
570
+ <VirtualHost test.host>
571
+ DocumentRoot /var/rails/zena/sites/example.com/public
572
+ PassengerAppRoot /var/rails/zena # <-- normally Phusion Passenger would
573
+ # have assumed that the application
574
+ # root is "/var/rails/zena/sites/example.com"
575
+ </VirtualHost>
576
+ -----------------------------
577
+
578
+ [[PassengerUseGlobalQueue]]
579
+ === PassengerUseGlobalQueue <on|off> ===
580
+ Turns the use of global queuing on or off.
581
+
582
+ This option may occur in the following places:
583
+
584
+ * In the global server configuration.
585
+ * In a virtual host configuration block.
586
+
587
+ In each place, it may be specified at most once. The default value is 'off'.
588
+
589
+ 'This feature is sponsored by http://www.37signals.com/[37signals].'
590
+
591
+ .What does this option do?
592
+
593
+ Recall that Phusion Passenger spawns multiple backend processes (e.g. multiple
594
+ Ruby on Rails processes), each which processes HTTP requests serially. One of
595
+ Phusion Passenger's jobs is to forward HTTP requests to a suitable backend
596
+ process. A backend process may take an arbitrary amount of time to process a
597
+ specific HTTP request. If the websites are (temporarily) under high load, and
598
+ the backend processes cannot process the requests fast enough, then some
599
+ requests may have to be queued.
600
+
601
+ If global queuing is turned off, then Phusion Passenger will use 'fair load
602
+ balancing'. This means that each backend process will have its own private
603
+ queue. Phusion Passenger will forward an HTTP request to the backend process
604
+ that has the least amount of requests in its queue.
605
+
606
+ If global queuing is turned on, then Phusion Passenger will use a global queue
607
+ that's shared between all backend processes. If an HTTP request comes in, and
608
+ all the backend processes are still busy, then Phusion Passenger will wait until
609
+ at least one backend process is done, and will then forward the request to that
610
+ process.
611
+
612
+ .When to turn on global queuing?
613
+
614
+ You should turn on global queuing if one of your web applications may have
615
+ long-running requests.
616
+
617
+ For example suppose that:
618
+
619
+ - global queuing is turned off.
620
+ - we're currently in a state where all backend processes have 3 requests in
621
+ their queue, except for a single backend process, which has 1 request in its
622
+ queue.
623
+
624
+ The situation looks like this:
625
+
626
+ --------------------------------------------------
627
+ Backend process A: [* ] (1 request in queue)
628
+ Backend process B: [*** ] (3 requests in queue)
629
+ Backend process C: [*** ] (3 requests in queue)
630
+ Backend process D: [*** ] (3 requests in queue)
631
+ --------------------------------------------------
632
+
633
+ Each process is currently serving short-running requests.
634
+
635
+ Phusion Passenger will forward the next request to backend process A. A will
636
+ now have 2 items in its queue. We'll mark this new request with an X:
637
+
638
+ --------------------------------------------------
639
+ Backend process A: [*X ] (2 request in queue)
640
+ Backend process B: [*** ] (3 requests in queue)
641
+ Backend process C: [*** ] (3 requests in queue)
642
+ Backend process D: [*** ] (3 requests in queue)
643
+ --------------------------------------------------
644
+
645
+ Assuming that B, C and D still aren't done with their current request, the next
646
+ HTTP request - let's call this Y - will be forwarded to backend process A as
647
+ well, because it has the least number of items in its queue:
648
+
649
+ --------------------------------------------------
650
+ Backend process A: [*XY ] (3 requests in queue)
651
+ Backend process B: [*** ] (3 requests in queue)
652
+ Backend process C: [*** ] (3 requests in queue)
653
+ Backend process D: [*** ] (3 requests in queue)
654
+ --------------------------------------------------
655
+
656
+ But if request X happens to be a long-running request that needs 60 seconds to
657
+ complete, then we'll have a problem. Y won't be processed for at least 60
658
+ seconds. It would have been a better idea if Y was forward to processes B, C or
659
+ D instead, because they only have short-living requests in their queues.
660
+
661
+ This problem will be avoided entirely if you turn global queuing on. With global
662
+ queuing, all backend processes will share the same queue. The first backend
663
+ process that becomes available will take from the queue, and so this
664
+ ``queuing-behind-long-running-request'' problem will never occur.
665
+
666
+ Turning global queuing off will yield a minor performance improvement (about 5%,
667
+ depending on how fast/slow your web application is), which is why it's off by
668
+ default.
669
+
670
+
671
+ [[PassengerUserSwitching]]
672
+ === PassengerUserSwitching <on|off> ===
673
+ Whether to enable <<user_switching,user switching support>>.
674
+
675
+ This option may only occur once, in the global server configuration.
676
+ The default value is 'on'.
677
+
678
+ [[PassengerDefaultUser]]
679
+ === PassengerDefaultUser <username> ===
680
+ Passenger enables <<user_switching,user switching support>> by default.
681
+ This configuration option allows one to specify which user Rails/Rack
682
+ applications must run as, if user switching fails or is disabled.
683
+
684
+ This option may only occur once, in the global server configuration.
685
+ The default value is 'nobody'.
686
+
687
+ [[PassengerHighPerformance]]
688
+ === PassengerHighPerformance <on|off> ===
689
+ By default, Phusion Passenger is compatible with mod_rewrite and most other
690
+ Apache modules. However, a lot of effort is required in order to be compatible.
691
+ If you turn 'PassengerHighPerformance' to 'on', then Phusion Passenger will be
692
+ a little faster, in return for reduced compatibility with other Apache modules.
693
+
694
+ In places where 'PassengerHighPerformance' is turned on, mod_rewrite rules will
695
+ likely not work. mod_autoindex (the module which displays a directory index)
696
+ will also not work. Other Apache modules may or may not work, depending on what
697
+ they exactly do. We recommend you to find out how other modules behave in high
698
+ performance mode via testing.
699
+
700
+ This option is *not* an all-or-nothing global option: you can enable high
701
+ performance mode for certain virtual hosts or certain URLs only.
702
+ The 'PassengerHighPerformance' option may occur in the following places:
703
+
704
+ * In the global server configuration.
705
+ * In a virtual host configuration block.
706
+ * In a `<Directory>` or `<Location>` block.
707
+ * In '.htaccess'.
708
+
709
+ In each place, it may be specified at most once. The default value is 'off',
710
+ so high performance mode is disabled by default, and you have to explicitly
711
+ enable it.
712
+
713
+ .When to enable high performance mode?
714
+
715
+ If you do not use mod_rewrite or other Apache modules then it might make
716
+ sense to enable high performance mode.
717
+
718
+ It's likely that some of your applications depend on mod_rewrite or other
719
+ Apache modules, while some do not. In that case you can enable high performance
720
+ for only those applications that don't use other Apache modules. For example:
721
+
722
+ ------------------------------------
723
+ <VirtualHost *:80>
724
+ ServerName www.foo.com
725
+ DocumentRoot /apps/foo/public
726
+ .... mod_rewrite rules or options for other Apache modules here ...
727
+ </VirtualHost>
728
+
729
+ <VirtualHost *:80>
730
+ ServerName www.bar.com
731
+ DocumentRoot /apps/bar/public
732
+ PassengerHighPerformance on
733
+ </VirtualHost>
734
+ ------------------------------------
735
+
736
+ In the above example, high performance mode is only enabled for www.bar.com.
737
+ It is disabled for everything else.
738
+
739
+ If your application generally depends on mod_rewrite or other Apache modules,
740
+ but a certain URL that's accessed often doesn't depend on those other modules,
741
+ then you can enable high performance mode for a certain URL only. For example:
742
+
743
+ ------------------------------------
744
+ <VirtualHost *:80>
745
+ ServerName www.foo.com
746
+ DocumentRoot /apps/foo/public
747
+ .... mod_rewrite rules or options for other Apache modules here ...
748
+
749
+ <Location /chatroom/ajax_update_poll>
750
+ PassengerHighPerformance on
751
+ </Location>
752
+ </VirtualHost>
753
+ ------------------------------------
754
+
755
+ This enables high performance mode for
756
+ http://www.foo.com/chatroom/ajax_update_poll only.
757
+
758
+ === PassengerEnabled <on|off> ===
759
+ You can set this option to 'off' to completely disable Phusion Passenger for
760
+ a certain location. This is useful if, for example, you want to integrate a PHP
761
+ application into the same virtual host as a Rails application.
762
+
763
+ Suppose that you have a Rails application in '/apps/foo'. Suppose that you've
764
+ dropped Wordpress -- a blogging application written in PHP -- in
765
+ '/apps/foo/public/wordpress'. You can then configure Phusion Passenger as
766
+ follows:
767
+
768
+ ------------------------------------
769
+ <VirtualHost *:80>
770
+ ServerName www.foo.com
771
+ DocumentRoot /apps/foo/public
772
+ <Location /wordpress>
773
+ PassengerEnabled off
774
+ </Location>
775
+ </VirtualHost>
776
+ ------------------------------------
777
+
778
+ This way, Phusion Passenger will not interfere with Wordpress.
779
+
780
+ 'PassengerEnabled' may occur in the following places:
781
+
782
+ * In the global server configuration.
783
+ * In a virtual host configuration block.
784
+ * In a `<Directory>` or `<Location>` block.
785
+ * In '.htaccess'.
786
+
787
+ In each place, it may be specified at most once. The default value is 'on'.
788
+
789
+ === PassengerTempDir <directory> ===
790
+ Specifies the directory that Phusion Passenger should use for storing temporary
791
+ files. This includes things such as Unix socket files, buffered file uploads,
792
+ etc.
793
+
794
+ This option may be specified once, in the global server configuration. The
795
+ default temp directory that Phusion Passenger uses is '/tmp'.
796
+
797
+ This option is especially useful if Apache is not allowed to write to /tmp
798
+ (which is the case on some systems with strict SELinux policies) or if the
799
+ partition that /tmp lives on doesn't have enough disk space.
800
+
801
+ .Command line tools
802
+ Some Phusion Passenger command line administration tools, such as
803
+ `passenger-status`, must know what Phusion Passenger's temp directory is
804
+ in order to function properly. You can pass the directory through the
805
+ `PASSENGER_TMPDIR` environment variable, or the `TMPDIR` environment variable
806
+ (the former will be used if both are specified).
807
+
808
+ For example, if you set 'PassengerTempDir' to '/my_temp_dir', then invoke
809
+ `passenger-status` after you've set the `PASSENGER_TMPDIR` or `TMPDIR`
810
+ environment variable, like this:
811
+
812
+ ----------------------------------------------------------
813
+ export PASSENGER_TMPDIR=/my_temp-dir
814
+ sudo -E passenger-status
815
+ # The -E option tells 'sudo' to preserve environment variables.
816
+ ----------------------------------------------------------
817
+
818
+ === PassengerRestartDir <directory> ===
819
+ As described in the deployment chapters of this document, Phusion Passenger
820
+ checks the file 'tmp/restart.txt' in the applications'
821
+ <<application_root,root directory>> for restarting applications. Sometimes it
822
+ may be desirable for Phusion Passenger to look in a different directory instead,
823
+ for example for security reasons (see below). This option allows you to
824
+ customize the directory in which 'restart.txt' is searched for.
825
+
826
+ You may specify 'PassengerRestartDir' in the following places:
827
+
828
+ * In the global server configuration.
829
+ * In a virtual host configuration block.
830
+ * In a `<Directory>` or `<Location>` block.
831
+ * In '.htaccess', if `AllowOverrides Options` is enabled.
832
+
833
+ In each place, it may be specified at most once.
834
+
835
+ You can either set it to an absolute directory, or to a directory relative to
836
+ the <<application_root,application root>>. Examples:
837
+
838
+ -----------------------------------
839
+ <VirtualHost *:80>
840
+ ServerName www.foo.com
841
+ # Phusion Passenger will check for /apps/foo/public/tmp/restart.txt
842
+ DocumentRoot /apps/foo/public
843
+ </VirtualHost>
844
+
845
+ <VirtualHost *:80>
846
+ ServerName www.bar.com
847
+ DocumentRoot /apps/bar/public
848
+ # An absolute filename is given; Phusion Passenger will
849
+ # check for /restart_files/bar/restart.txt
850
+ PassengerRestartDir /restart_files/bar
851
+ </VirtualHost>
852
+
853
+ <VirtualHost *:80>
854
+ ServerName www.baz.com
855
+ DocumentRoot /apps/baz/public
856
+ # A relative filename is given; Phusion Passenger will
857
+ # check for /apps/baz/restart_files/restart.txt
858
+ #
859
+ # Note that this directory is relative to the APPLICATION ROOT, *not*
860
+ # the value of DocumentRoot!
861
+ PassengerRestartDir restart_files
862
+ </VirtualHost>
863
+ -----------------------------------
864
+
865
+ .What are the security reasons for wanting to customize PassengerRestartDir?
866
+ Touching restart.txt will cause Phusion Passenger to restart the application.
867
+ So anybody who can touch restart.txt can effectively cause a Denial-of-Service
868
+ attack by touching restart.txt over and over. If your web server or one of your
869
+ web applications has the permission to touch restart.txt, and one of them has a
870
+ security flaw which allows an attacker to touch restart.txt, then that will
871
+ allow the attacker to cause a Denial-of-Service.
872
+
873
+ You can prevent this from happening by pointing PassengerRestartDir to a
874
+ directory that's readable by Apache, but only writable by administrators.
875
+
876
+
877
+ === Resource control and optimization options ===
878
+
879
+ ==== PassengerMaxPoolSize <integer> ====
880
+ The maximum number of Ruby on Rails or Rack application instances that may
881
+ be simultaneously active. A larger number results in higher memory usage,
882
+ but improved ability to handle concurrent HTTP clients.
883
+
884
+ The optimal value depends on your system's hardware and the server's average
885
+ load. You should experiment with different values. But generally speaking,
886
+ the value should be at least equal to the number of CPUs (or CPU cores) that
887
+ you have. If your system has 2 GB of RAM, then we recommend a value of '30'.
888
+ If your system is a Virtual Private Server (VPS) and has about 256 MB RAM, and
889
+ is also running other services such as MySQL, then we recommend a value of '2'.
890
+
891
+ If you find that your server is unable to handle the load on your Rails/Rack websites
892
+ (i.e. running out of memory) then you should lower this value. (Though if your
893
+ sites are really that popular, then you should strongly consider upgrading your
894
+ hardware or getting more servers.)
895
+
896
+ This option may only occur once, in the global server configuration.
897
+ The default value is '6'.
898
+
899
+ TIP: We strongly recommend you to <<reducing_memory_usage,use Ruby Enterprise
900
+ Edition>>. This allows you to reduce the memory usage of your Ruby on Rails applications
901
+ by about 33%. And it's not hard to install.
902
+
903
+ ==== PassengerMaxInstancesPerApp <integer> ====
904
+ The maximum number of application instances that may be simultaneously active
905
+ for a single application. This helps to make sure that a single application
906
+ will not occupy all available slots in the application pool.
907
+
908
+ This value must be less than <<PassengerMaxPoolSize,PassengerMaxPoolSize>>. A value of 0
909
+ means that there is no limit placed on the number of instances a single application
910
+ may use, i.e. only the global limit of <<PassengerMaxPoolSize,PassengerMaxPoolSize>>
911
+ will be enforced.
912
+
913
+ This option may only occur once, in the global server configuration.
914
+ The default value is '0'.
915
+
916
+ [[PassengerPoolIdleTime]]
917
+ ==== PassengerPoolIdleTime <integer> ====
918
+ The maximum number of seconds that an application instance may be idle. That is,
919
+ if an application instance hasn't received any traffic after the given number of
920
+ seconds, then it will be shutdown in order to conserve memory.
921
+
922
+ Decreasing this value means that applications will have to be spawned
923
+ more often. Since spawning is a relatively slow operation, some visitors may
924
+ notice a small delay when they visit your Rails/Rack website. However, it will also
925
+ free up resources used by applications more quickly.
926
+
927
+ The optimal value depends on the average time that a visitor spends on a single
928
+ Rails/Rack web page. We recommend a value of `2 * x`, where `x` is the average
929
+ number of seconds that a visitor spends on a single Rails/Rack web page. But your
930
+ mileage may vary.
931
+
932
+ When this value is set to '0', application instances will not be shutdown unless
933
+ it's really necessary, i.e. when Phusion Passenger is out of worker processes
934
+ for a given application and one of the inactive application instances needs to
935
+ make place for another application instance. Setting the value to 0 is
936
+ recommended if you're on a non-shared host that's only running a few
937
+ applications, each which must be available at all times.
938
+
939
+ This option may only occur once, in the global server configuration.
940
+ The default value is '300'.
941
+
942
+ [[PassengerMaxRequests]]
943
+ ==== PassengerMaxRequests <integer> ====
944
+ The maximum number of requests an application instance will process. After
945
+ serving that many requests, the application instance will be shut down and
946
+ Phusion Passenger will restart it. A value of 0 means that there is no maximum:
947
+ an application instance will thus be shut down when its idle timeout has been
948
+ reached.
949
+
950
+ This option is useful if your application is leaking memory. By shutting
951
+ it down after a certain number of requests, all of its memory is guaranteed
952
+ to be freed by the operating system.
953
+
954
+ This option may occur in the following places:
955
+
956
+ * In the global server configuration.
957
+ * In a virtual host configuration block.
958
+ * In a `<Directory>` or `<Location>` block.
959
+ * In '.htaccess', if `AllowOverride Limits` is on.
960
+
961
+ In each place, it may be specified at most once. The default value is '0'.
962
+
963
+ [CAUTION]
964
+ =====================================================
965
+ The <<PassengerMaxRequests,PassengerMaxRequests>> directive should be considered
966
+ as a workaround for misbehaving applications. It is advised that you fix the
967
+ problem in your application rather than relying on these directives as a
968
+ measure to avoid memory leaks.
969
+ =====================================================
970
+
971
+ ==== PassengerStatThrottleRate <integer> ====
972
+ By default, Phusion Passenger performs several filesystem checks (or, in
973
+ programmers jargon, 'stat() calls') each time a request is processed:
974
+
975
+ - It checks whether 'config/environment.rb', 'config.ru' or 'passenger_wsgi.py'
976
+ is present, in order to autodetect Rails, Rack and WSGI applications.
977
+ - It checks whether 'restart.txt' has changed or whether 'always_restart.txt'
978
+ exists, in order to determine whether the application should be restarted.
979
+
980
+ On some systems where disk I/O is expensive, e.g. systems where the harddisk is
981
+ already being heavily loaded, or systems where applications are stored on NFS
982
+ shares, these filesystem checks can incur a lot of overhead.
983
+
984
+ You can decrease or almost entirely eliminate this overhead by setting
985
+ 'PassengerStatThrottleRate'. Setting this option to a value of 'x' means that
986
+ the above list of filesystem checks will be performed at most once every 'x'
987
+ seconds. Setting it to a value of '0' means that no throttling will take place,
988
+ or in other words, that the above list of filesystem checks will be performed on
989
+ every request.
990
+
991
+ This option may occur in the following places:
992
+
993
+ * In the global server configuration.
994
+ * In a virtual host configuration block.
995
+ * In a `<Directory>` or `<Location>` block.
996
+ * In '.htaccess', if `AllowOverride Limits` is on.
997
+
998
+ In each place, it may be specified at most once. The default value is '0'.
999
+
1000
+
1001
+ === Ruby on Rails-specific options ===
1002
+
1003
+ ==== RailsAutoDetect <on|off> ====
1004
+ Whether Phusion Passenger should automatically detect whether a virtual host's
1005
+ document root is a Ruby on Rails application. The default is 'on'.
1006
+
1007
+ This option may occur in the global server configuration or in a virtual host
1008
+ configuration block.
1009
+
1010
+ For example, consider the following configuration:
1011
+
1012
+ -----------------------------
1013
+ RailsAutoDetect off
1014
+ <VirtualHost *:80>
1015
+ ServerName www.mycook.com
1016
+ DocumentRoot /webapps/mycook/public
1017
+ </VirtualHost>
1018
+ -----------------------------
1019
+
1020
+ If one goes to 'http://www.mycook.com/', the visitor will see the contents of
1021
+ the '/webapps/mycook/public' folder, instead of the output of the Ruby on Rails
1022
+ application.
1023
+
1024
+ It is possible to explicitly specify that the host is a Ruby on Rails
1025
+ application by using the <<RailsBaseURI,RailsBaseURI>> configuration option:
1026
+
1027
+ -----------------------------
1028
+ RailsAutoDetect off
1029
+ <VirtualHost *:80>
1030
+ ServerName www.mycook.com
1031
+ DocumentRoot /webapps/mycook/public
1032
+ RailsBaseURI / # This line has been added.
1033
+ </VirtualHost>
1034
+ -----------------------------
1035
+
1036
+ [[RailsBaseURI]]
1037
+ ==== RailsBaseURI <uri> ====
1038
+ Used to specify that the given URI is a Rails application. See
1039
+ <<deploying_rails_to_sub_uri,Deploying Rails to a sub URI>> for an example.
1040
+
1041
+ It is allowed to specify this option multiple times. Do this to deploy multiple
1042
+ Rails applications in different sub-URIs under the same virtual host.
1043
+
1044
+ This option may occur in the following places:
1045
+
1046
+ * In the global server configuration.
1047
+ * In a virtual host configuration block.
1048
+ * In a `<Directory>` or `<Location>` block.
1049
+ * In '.htaccess', if `AllowOverride Options` is on.
1050
+
1051
+ [[rails_env]]
1052
+ ==== RailsEnv <string> ====
1053
+ This option allows one to specify the default `RAILS_ENV` value.
1054
+
1055
+ This option may occur in the following places:
1056
+
1057
+ * In the global server configuration.
1058
+ * In a virtual host configuration block.
1059
+ * In a `<Directory>` or `<Location>` block.
1060
+ * In '.htaccess', if `AllowOverride Options` is on.
1061
+
1062
+ In each place, it may be specified at most once. The default value is 'production'.
1063
+
1064
+ [[RailsSpawnMethod]]
1065
+ ==== RailsSpawnMethod <string> ====
1066
+ [TIP]
1067
+ ."What spawn method should I use?"
1068
+ =========================================================
1069
+ This subsection attempts to describe spawn methods, but it's okay if you don't (want to)
1070
+ understand it, as it's mostly a technical detail. You can basically follow this rule of thumb:
1071
+
1072
+ ************************************************
1073
+ If your application works on Mongrel, but not on Phusion Passenger, then set
1074
+ `RailsSpawnMethod` to 'conservative'. Otherwise, leave it at 'smart-lv2' (the default).
1075
+ ************************************************
1076
+
1077
+ However, we do recommend you to try to understand it. The 'smart' and 'smart-lv2' spawn
1078
+ methods bring many benefits.
1079
+ =========================================================
1080
+
1081
+ Internally, Phusion Passenger spawns multiple Ruby on Rails processes in order to handle
1082
+ requests. But there are multiple ways with which processes can be spawned, each having
1083
+ its own set of pros and cons. Supported spawn methods are:
1084
+
1085
+ 'smart'::
1086
+ When this spawn method is used, Phusion Passenger will attempt to cache Ruby on Rails
1087
+ framework code and application code for a limited period of time. Please read
1088
+ <<spawning_methods_explained,Spawning methods explained>> for a more detailed
1089
+ explanation of what smart spawning exactly does.
1090
+ +
1091
+ *Pros:*
1092
+ This can significantly decrease spawn time (by as much as 90%). And, when Ruby Enterprise
1093
+ Edition is used, <<reducing_memory_usage,memory usage can be reduced by 33% on average>>.
1094
+ +
1095
+ *Cons:*
1096
+ Some Ruby on Rails applications and libraries are not compatible with smart spawning.
1097
+ If that's the case for your application, then you should use 'conservative' as
1098
+ spawning method.
1099
+
1100
+ 'smart-lv2'::
1101
+ This spawning method is similar to 'smart' but it skips the framework spawner
1102
+ and uses the application spawner directly. This means the framework code is not
1103
+ cached between multiple applications, although it is still cached within
1104
+ instances of the same application. Please read
1105
+ <<spawning_methods_explained,Spawning methods explained>> for a more detailed
1106
+ explanation of what smart-lv2 spawning exactly does.
1107
+ +
1108
+ *Pros:* It is compatible with a larger number of applications when compared to
1109
+ the 'smart' method, and still performs some caching.
1110
+ +
1111
+ *Cons:* It is slower than smart spawning if you have many applications which
1112
+ use the same framework version. It is therefore advised that shared hosts use the
1113
+ 'smart' method instead.
1114
+
1115
+ 'conservative'::
1116
+ This spawning method is similar to the one used in Mongrel Cluster. It does not
1117
+ perform any code caching at all. Please read
1118
+ <<spawning_methods_explained,Spawning methods explained>> for a more detailed
1119
+ explanation of what conservative spawning exactly does.
1120
+ +
1121
+ *Pros:*
1122
+ Conservative spawning is guaranteed to be compatible with all Rails applications
1123
+ and libraries.
1124
+ +
1125
+ *Cons:*
1126
+ Much slower than smart spawning. Every spawn action will be equally slow, though no slower than
1127
+ the startup time of a single server in Mongrel Cluster. Conservative spawning will also
1128
+ render <<reducing_memory_usage,Ruby Enterprise Edition's memory reduction technology>> useless.
1129
+
1130
+ This option may occur in the following places:
1131
+
1132
+ * In the global server configuration.
1133
+ * In a virtual host configuration block.
1134
+
1135
+ In each place, it may be specified at most once. The default value is 'smart-lv2'.
1136
+
1137
+ === Rack-specific options ===
1138
+
1139
+ ==== RackAutoDetect <on|off> ====
1140
+ Whether Phusion Passenger should automatically detect whether a virtual host's
1141
+ document root is a Rack application. The default is 'on'.
1142
+
1143
+ This option may occur in the global server configuration or in a virtual host
1144
+ configuration block.
1145
+
1146
+ For example, consider the following configuration:
1147
+
1148
+ -----------------------------
1149
+ RackAutoDetect off
1150
+ <VirtualHost *:80>
1151
+ ServerName www.rackapp.com
1152
+ DocumentRoot /webapps/my_rack_app/public
1153
+ </VirtualHost>
1154
+ -----------------------------
1155
+
1156
+ If one goes to 'http://www.rackapp.com/', the visitor will see the contents of
1157
+ the '/webapps/my_rack_app/public' folder, instead of the output of the Rack
1158
+ application.
1159
+
1160
+ It is possible to explicitly specify that the host is a Rack
1161
+ application by using the <<RackBaseURI,RackBaseURI>> configuration option:
1162
+
1163
+ -----------------------------
1164
+ RackAutoDetect off
1165
+ <VirtualHost *:80>
1166
+ ServerName www.rackapp.com
1167
+ DocumentRoot /webapps/my_rack_app/public
1168
+ RackBaseURI / # This line was added
1169
+ </VirtualHost>
1170
+ -----------------------------
1171
+
1172
+ [[RackBaseURI]]
1173
+ ==== RackBaseURI <uri> ====
1174
+ Used to specify that the given URI is a Rack application. See
1175
+ <<deploying_rack_to_sub_uri,Deploying Rack to a sub URI>> for an example.
1176
+
1177
+ It is allowed to specify this option multiple times. Do this to deploy multiple
1178
+ Rack applications in different sub-URIs under the same virtual host.
1179
+
1180
+ This option may occur in the following places:
1181
+
1182
+ * In the global server configuration.
1183
+ * In a virtual host configuration block.
1184
+ * In a `<Directory>` or `<Location>` block.
1185
+ * In '.htaccess', if `AllowOverride Options` is on.
1186
+
1187
+ [[rack_env]]
1188
+ ==== RackEnv <string> ====
1189
+ The given value will be accessible in Rack applications in the `RACK_ENV`
1190
+ environment variable. This allows one to define the environment in which
1191
+ Rack applications are run, very similar to `RAILS_ENV`.
1192
+
1193
+ This option may occur in the following places:
1194
+
1195
+ * In the global server configuration.
1196
+ * In a virtual host configuration block.
1197
+ * In a `<Directory>` or `<Location>` block.
1198
+ * In '.htaccess', if `AllowOverride Options` is on.
1199
+
1200
+ In each place, it may be specified at most once. The default value is 'production'.
1201
+
1202
+ === Deprecated options ===
1203
+
1204
+ The following options have been deprecated, but are still supported for backwards
1205
+ compatibility reasons.
1206
+
1207
+ ==== RailsRuby ====
1208
+ Deprecated in favor of <<PassengerRuby,PassengerRuby>>.
1209
+
1210
+ ==== RailsUserSwitching ====
1211
+ Deprecated in favor of <<PassengerUserSwitching,PassengerUserSwitching>>.
1212
+
1213
+ ==== RailsDefaultUser ====
1214
+ Deprecated in favor of <<PassengerDefaultUser,PassengerDefaultUser>>.
1215
+
1216
+ ==== RailsAllowModRewrite ====
1217
+ This option doesn't do anything anymore in recent versions of Phusion Passenger.
1218
+
1219
+
1220
+ == Troubleshooting ==
1221
+
1222
+ === Operating system-specific problems ===
1223
+
1224
+ ==== MacOS X: The installer cannot locate MAMP's Apache ====
1225
+
1226
+ .Symptoms
1227
+ *******************************************************************************
1228
+ The installer finds Apache 2 development headers at `/Applications/MAMP/Library/bin/apxs`.
1229
+ However, Apache cannot be found. The installer also outputs the following error:
1230
+ ------------------------------------
1231
+ cannot open /Applications/MAMP/Library/build/config_vars.mk:
1232
+ No such file or directory at /Applications/MAMP/Library/bin/apxs line 218.
1233
+ ------------------------------------
1234
+ *******************************************************************************
1235
+
1236
+ Your MAMP installation seems to be broken. In particular, 'config_vars.mk' is missing.
1237
+ Please read link:http://forum.mamp.info/viewtopic.php?t=1866[this forum topic] to learn how
1238
+ to fix this problem.
1239
+
1240
+ See also link:http://code.google.com/p/phusion-passenger/issues/detail?id=12[this bug report].
1241
+
1242
+
1243
+ === Problems during installation ===
1244
+
1245
+ [[installing_ruby_dev]]
1246
+ ==== Ruby development headers aren't installed ====
1247
+
1248
+ .Symptoms
1249
+ *******************************************************************************
1250
+ Installing Phusion Passenger fails because of one of the following errors:
1251
+
1252
+ - The Phusion Passenger installer tells you that the Ruby development headers
1253
+ aren't installed.
1254
+ - The error message ``'no such file to load -- mkmf''' occurs.
1255
+ - The error message ``'ruby.h: No such file or directory''' occurs.
1256
+ *******************************************************************************
1257
+
1258
+ Phusion Passenger makes use of a native extension, so the Ruby development headers
1259
+ must be installed. On most Linux systems, Ruby and the Ruby development headers
1260
+ are contained in separate packages, so having Ruby installed does not
1261
+ automatically imply having the development headers installed.
1262
+
1263
+ Here's how you can install the development headers:
1264
+
1265
+ Ubuntu/Debian::
1266
+ Please type:
1267
+ +
1268
+ -----------------------------------------
1269
+ sudo apt-get install ruby1.8-dev
1270
+ -----------------------------------------
1271
+
1272
+ Fedora/CentOS/RHEL::
1273
+ Please type:
1274
+ +
1275
+ -----------------------------------------
1276
+ su -c 'yum install ruby-devel'
1277
+ -----------------------------------------
1278
+
1279
+ FreeBSD::
1280
+ Please install Ruby from 'ports' or with `pkg_add`. If that fails,
1281
+ please install Ruby from source.
1282
+
1283
+ MacOS X::
1284
+ Please install Ruby from source.
1285
+
1286
+ Other operating systems::
1287
+ Please consult your operating system's native package database.
1288
+ There should be a package containing the Ruby development headers.
1289
+ If that fails, please install Ruby from source.
1290
+
1291
+ NOTE: If you've installed a new Ruby version (i.e. your system now contains
1292
+ multiple Ruby installations), then you will need to tell Phusion Passenger
1293
+ which Ruby installation you want to use. Please read
1294
+ <<specifying_ruby_installation,Specifying the correct Ruby installation>>.
1295
+
1296
+ ==== Apache development headers aren't installed ====
1297
+
1298
+ .Symptoms
1299
+ *******************************************************************************
1300
+ Installing Phusion Passenger fails because of one of the following errors:
1301
+
1302
+ - The installer says that the Apache development headers aren't installed.
1303
+ - The error message ``'httpd.h: No such file or directory''' occurs.
1304
+ +
1305
+ (Instead of 'httpd.h', the message might also be 'http_config.h' or something
1306
+ else similar to 'http_*.h'.)
1307
+ *******************************************************************************
1308
+
1309
+ Ubuntu::
1310
+ Please type:
1311
+ +
1312
+ -----------------------------------------
1313
+ sudo apt-get install apache2-prefork-dev
1314
+ -----------------------------------------
1315
+
1316
+ Debian::
1317
+ Please type:
1318
+ +
1319
+ -----------------------------------------
1320
+ sudo apt-get install apache2-dev
1321
+ -----------------------------------------
1322
+
1323
+ Fedora/CentOS/RHEL::
1324
+ Please type:
1325
+ +
1326
+ --------------------------------
1327
+ su -c 'yum install httpd-devel'
1328
+ --------------------------------
1329
+
1330
+ FreeBSD::
1331
+ Please install Apache from 'ports' or with `pkg_add`. If that fails,
1332
+ please install Apache from source.
1333
+
1334
+ MacOS X::
1335
+ Please install Apache from source.
1336
+
1337
+ Other operating systems::
1338
+ Please consult your operating system's native package database.
1339
+ There should be a package containing the Apache development headers.
1340
+ If that fails, please install Apache from source.
1341
+
1342
+
1343
+ ==== APR development headers aren't installed ====
1344
+
1345
+ .Symptoms
1346
+ *******************************************************************************
1347
+ Installing Phusion Passenger fails because one of the following errors:
1348
+
1349
+ - The installer tells you that APR development headers aren't installed.
1350
+ - The error message ``'apr_pools.h: No such file or directory''' occurs.
1351
+ - The error message ``'apr_strings.h: No such file or directory''' occurs.
1352
+ *******************************************************************************
1353
+
1354
+ Ubuntu::
1355
+ Please type:
1356
+ +
1357
+ -----------------------------------------
1358
+ sudo apt-get install libapr1-dev
1359
+ -----------------------------------------
1360
+
1361
+ Debian::
1362
+ Please type:
1363
+ +
1364
+ -----------------------------------------
1365
+ sudo apt-get install libapr1-dev
1366
+ -----------------------------------------
1367
+
1368
+ Fedora/CentOS/RHEL::
1369
+ Please type:
1370
+ +
1371
+ --------------------------------
1372
+ su -c 'yum install apr-devel'
1373
+ --------------------------------
1374
+
1375
+ Other Linux distributions::
1376
+ Please consult your distribution's package database. There should be a
1377
+ package which provides APR development headers.
1378
+
1379
+ Other operating systems::
1380
+ The APR development are bundled with Apache. If the APR headers aren't,
1381
+ then it probably means that they have been removed after Apache's been
1382
+ installed. Please reinstall Apache to get back the APR headers.
1383
+
1384
+
1385
+ ==== Phusion Passenger is using the wrong Apache during installation ====
1386
+
1387
+ Please <<specifying_correct_apache_install,Specifying the correct Apache
1388
+ installation>>, and re-run the Phusion Passenger installer.
1389
+
1390
+
1391
+ ==== Phusion Passenger is using the wrong Ruby during installation ====
1392
+
1393
+ Please <<specifying_ruby_installation,Specifying the correct Ruby
1394
+ installation>>, and re-run the Phusion Passenger installer.
1395
+
1396
+
1397
+ === Problems after installation ===
1398
+
1399
+ [TIP]
1400
+ .The golden tip: read your Apache error logs!
1401
+ =====================================================
1402
+ 'mod_passenger' will write all errors to the Apache error log. So if
1403
+ you're experiencing post-installation problems, please look
1404
+ inside the Apache error logs. It will tell you what exactly went wrong.
1405
+ =====================================================
1406
+
1407
+ ==== My Rails application works on Mongrel, but not on Phusion Passenger ====
1408
+
1409
+ Please try setting <<RailsSpawnMethod,RailsSpawnMethod>> to 'conservative'.
1410
+
1411
+ ==== Phusion Passenger has been compiled against the wrong Apache installation ====
1412
+
1413
+ .Symptoms
1414
+ *******************************************************************************
1415
+ Apache crashes during startup (after being daemonized). The Apache error log
1416
+ says ``'seg fault or similar nasty error detected in the parent process'''.
1417
+ *******************************************************************************
1418
+
1419
+ This problem is most likely to occur on MacOS X. Most OS X users have multiple
1420
+ Apache installations on their system.
1421
+
1422
+ To solve this problem, please <<specifying_correct_apache_install,specify the
1423
+ correct Apache installation>>, and <<install_passenger,reinstall Phusion
1424
+ Passenger>>.
1425
+
1426
+ ==== I get a "304 Forbidden" error ====
1427
+
1428
+ See next subsection.
1429
+
1430
+ ==== Static assets such as images and stylesheets aren't being displayed ====
1431
+
1432
+ Static assets are accelerated, i.e. they are served directly by Apache and do not
1433
+ go through the Rails stack. There are two reasons why Apache doesn't serve static
1434
+ assets correctly:
1435
+
1436
+ 1. Your Apache configuration is too strict, and does not allow HTTP clients to
1437
+ access static assets. This can be achieved with an `Allow from all` directive
1438
+ in the correct place. For example:
1439
+ +
1440
+ -----------------------------------------
1441
+ <Directory "/webapps/mycook/public">
1442
+ Options FollowSymLinks
1443
+ AllowOverride None
1444
+ Order allow,deny
1445
+ Allow from all
1446
+ </Directory>
1447
+ -----------------------------------------
1448
+ +
1449
+ See also link:http://groups.google.com/group/phusion-passenger/browse_thread/thread/9699a639a87f85f4/b9d71a03bf2670a5[this discussion].
1450
+
1451
+ 2. The Apache process doesn't have permission to access your Rails application's folder.
1452
+ Please make sure that the Rails application's folder, as well as all of its parent folders,
1453
+ have the correct permissions and/or ownerships.
1454
+
1455
+ ==== The Apache error log says that the spawn manager script does not exist, or that it does not have permission to execute it ====
1456
+
1457
+ If you are sure that the 'PassengerRoot' configuration option is set correctly,
1458
+ then this problem is most likely caused by the fact that you're running Apache
1459
+ with SELinux. On Fedora, CentOS and RedHat Enterprise Linux, Apache is locked
1460
+ down by SELinux policies.
1461
+
1462
+ To solve this problem, you must set some permissions on the Phusion Passenger files
1463
+ and folders, so that Apache can access them.
1464
+
1465
+ - If you've installed Phusion Passenger via a gem, then run this command to determine
1466
+ Phusion Passenger's root folder:
1467
+ +
1468
+ ------------------------------------------------------------------
1469
+ passenger-config --root
1470
+ ------------------------------------------------------------------
1471
+ +
1472
+ Next, run the following command:
1473
+ +
1474
+ ------------------------------------------------------------------
1475
+ chcon -R -h -t httpd_sys_content_t /path-to-passenger-root
1476
+ ------------------------------------------------------------------
1477
+ +
1478
+ where '/path-to-passenger-root' should be replaced with whatever
1479
+ `passenger-config --root` printed.
1480
+
1481
+ - If you've installed Phusion Passenger via the source tarball, then run the following
1482
+ command:
1483
+ +
1484
+ ------------------------------------------------------------------
1485
+ chcon -R -h -t httpd_sys_content_t /path/to/passenger/folder
1486
+ ------------------------------------------------------------------
1487
+
1488
+ Once the permissions are fixed, restart Apache.
1489
+
1490
+ ==== The Rails application reports that it's unable to start because of a permission error ====
1491
+
1492
+ Please check whether your Rails application's folder has the correct
1493
+ permissions. By default, Rails applications are started as the owner of the
1494
+ file 'config/environment.rb', except if the file is owned by root. If the
1495
+ file is owned by root, then the Rails application will be started as 'nobody'
1496
+ (or as the user specify by <<RailsDefaultUser,RailsDefaultUser>>, if that's
1497
+ specified).
1498
+
1499
+ Please read <<user_switching,User switching (security)>> for details.
1500
+
1501
+ ==== My Rails application's log file is not being written to ====
1502
+
1503
+ There are a couple things that you should be aware of:
1504
+
1505
+ - By default, Phusion Passenger runs Rails applications in 'production' mode,
1506
+ so please be sure to check 'production.log' instead of 'development.log'. See
1507
+ <<RailsEnv,RailsEnv>> for configuration.
1508
+ - By default, Phusion Passenger runs Rails applications as the owner of 'environment.rb'.
1509
+ So the log file can only be written to if that user has write permission to the
1510
+ log file. Please 'chmod' or 'chown' your log file accordingly.
1511
+ +
1512
+ See <<User_switching,User switching (security)>> for details.
1513
+
1514
+ If you're using a RedHat-derived Linux distribution (such as Fedora or CentOS)
1515
+ then it is link:http://code.google.com/p/phusion-passenger/issues/detail?id=4[possible
1516
+ that SELinux is interfering]. RedHat's SELinux policy only allows Apache to read/write
1517
+ directories that have the 'httpd_sys_content_t' security context. Please run the
1518
+ following command to give your Rails application folder that context:
1519
+
1520
+ -----------------------------------------------------------
1521
+ chcon -R -h -t httpd_sys_content_t /path/to/your/rails/app
1522
+ -----------------------------------------------------------
1523
+
1524
+
1525
+ [[conflicting_apache_modules]]
1526
+ === Conflicting Apache modules ===
1527
+
1528
+ ==== mod_userdir ====
1529
+
1530
+ 'mod_userdir' is not compatible with Phusion Passenger at the moment.
1531
+
1532
+ ==== VirtualDocumentRoot ====
1533
+
1534
+ VirtualDocumentRoot is not compatible with Phusion Passenger at the moment.
1535
+
1536
+
1537
+ == Analysis and system maintenance tools ==
1538
+
1539
+ Phusion Passenger provides a set of tools, which are useful for system analysis,
1540
+ maintenance and troubleshooting.
1541
+
1542
+
1543
+ === Inspecting memory usage ===
1544
+
1545
+ Process inspection tools such as `ps` and `top` are useful, but they
1546
+ link:http://groups.google.com/group/phusion-passenger/msg/1fd1c233456d3180[rarely show the correct memory usage].
1547
+ The real memory usage is usually lower than what `ps` and `top` report.
1548
+
1549
+ There are many technical reasons why this is so, but an explanation is beyond
1550
+ the scope of this Users Guide. We kindly refer the interested reader to
1551
+ operating systems literature about 'virtual memory' and 'copy-on-write'.
1552
+
1553
+ The tool `passenger-memory-stats` allows one to easily analyze Phusion Passenger's
1554
+ and Apache's real memory usage. For example:
1555
+
1556
+ -------------------------------------------------------
1557
+ [bash@localhost root]# passenger-memory-stats
1558
+ ------------- Apache processes --------------.
1559
+ PID PPID Threads VMSize Private Name
1560
+ ---------------------------------------------.
1561
+ 5947 1 9 90.6 MB 0.5 MB /usr/sbin/apache2 -k start
1562
+ 5948 5947 1 18.9 MB 0.7 MB /usr/sbin/fcgi-pm -k start
1563
+ 6029 5947 1 42.7 MB 0.5 MB /usr/sbin/apache2 -k start
1564
+ 6030 5947 1 42.7 MB 0.5 MB /usr/sbin/apache2 -k start
1565
+ 6031 5947 1 42.5 MB 0.3 MB /usr/sbin/apache2 -k start
1566
+ 6033 5947 1 42.5 MB 0.4 MB /usr/sbin/apache2 -k start
1567
+ 6034 5947 1 50.5 MB 0.4 MB /usr/sbin/apache2 -k start
1568
+ 23482 5947 1 82.6 MB 0.4 MB /usr/sbin/apache2 -k start
1569
+ ### Processes: 8
1570
+ ### Total private dirty RSS: 3.50 MB
1571
+
1572
+ --------- Passenger processes ---------.
1573
+ PID Threads VMSize Private Name
1574
+ ---------------------------------------.
1575
+ 6026 1 10.9 MB 4.7 MB Passenger spawn server
1576
+ 23481 1 26.7 MB 3.0 MB Passenger FrameworkSpawner: 2.0.2
1577
+ 23791 1 26.8 MB 2.9 MB Passenger ApplicationSpawner: /var/www/projects/app1-foobar
1578
+ 23793 1 26.9 MB 17.1 MB Rails: /var/www/projects/app1-foobar
1579
+ ### Processes: 4
1580
+ ### Total private dirty RSS: 27.76 M
1581
+ -------------------------------------------------------
1582
+
1583
+ The 'Private' or 'private dirty RSS' field shows the *real* memory usage of processes. Here,
1584
+ we see that all the Apache worker processes only take less than 1 MB memory each.
1585
+ This is a lot less than the 50 MB-ish memory usage as shown in the 'VMSize' column
1586
+ (which is what a lot of people think is the real memory usage, but is actually not).
1587
+
1588
+ NOTE: This tool only works on Linux. Unfortunately other operating systems don't
1589
+ provide facilities for determining processes' private dirty RSS.
1590
+
1591
+
1592
+ === Inspecting Phusion Passenger's internal status ===
1593
+
1594
+ One can inspect Phusion Passenger's internal status with the tool `passenger-status`.
1595
+ This tool must typically be run as root. For example:
1596
+
1597
+ --------------------------------------------------
1598
+ [bash@localhost root]# passenger-status
1599
+ ----------- General information -----------
1600
+ max = 6
1601
+ count = 1
1602
+ active = 0
1603
+ inactive = 1
1604
+
1605
+ ----------- Domains -----------
1606
+ /var/www/projects/app1-foobar:
1607
+ PID: 9617 Sessions: 0 Processed: 7 Uptime: 2m 23s
1608
+ --------------------------------------------------
1609
+
1610
+ The 'general information' section shows the following information:
1611
+
1612
+ max:: The maximum number of application instances that Phusion Passenger will
1613
+ spawn. This equals the value given for <<PassengerMaxPoolSize,PassengerMaxPoolSize>>.
1614
+ count:: The number of application instances that are currently alive. This value
1615
+ is always less than or equal to 'max'.
1616
+ active:: The number of application instances that are currently processing
1617
+ requests. This value is always less than or equal to 'count'.
1618
+ inactive:: The number of application instances that are currently *not* processing
1619
+ requests, i.e. are idle. Idle application instances will be shutdown after a while,
1620
+ as can be specified with <<PassengerPoolIdleTime,PassengerPoolIdleTime>> (unless this
1621
+ value is set to 0, in which case application instances are never shut down via idle
1622
+ time). The value of 'inactive' equals `count - active`.
1623
+
1624
+ The 'domains' section shows, for each application directory, information about running
1625
+ application instances:
1626
+
1627
+ Sessions:: Shows how many HTTP client are currently in the queue of that application
1628
+ Instance, waiting to be processed.
1629
+ Processed:: Indicates how many requests the instance has served until now. *Tip:* it's
1630
+ possible to limit this number with the <<PassengerMaxRequests,PassengerMaxRequests>>
1631
+ configuration directive.
1632
+ Uptime:: Shows for how long the application instance has been running.
1633
+
1634
+ Since Phusion Passenger uses fair load balancing by default, the number of sessions for the
1635
+ application instances should be fairly close to each other. For example, this is fairly
1636
+ normal:
1637
+ --------------------------------
1638
+ PID: 4281 Sessions: 2 Processed: 7 Uptime: 5m 11s
1639
+ PID: 4268 Sessions: 0 Processed: 5 Uptime: 4m 52s
1640
+ PID: 4265 Sessions: 1 Processed: 6 Uptime: 5m 38s
1641
+ PID: 4275 Sessions: 1 Processed: 7 Uptime: 3m 14s
1642
+ --------------------------------
1643
+
1644
+ But if you see a "spike", i.e. an application instance has an unusually high number of
1645
+ sessions compared to the others, then there might be a problem:
1646
+ --------------------------------
1647
+ PID: 4281 Sessions: 2 Processed: 7 Uptime: 5m 11s
1648
+ PID: 17468 Sessions: 8 <-+ Processed: 2 Uptime: 4m 47s
1649
+ PID: 4265 Sessions: 1 | Processed: 6 Uptime: 5m 38s
1650
+ PID: 4275 Sessions: 1 | Processed: 7 Uptime: 3m 14s
1651
+ |
1652
+ +---- "spike"
1653
+ --------------------------------
1654
+
1655
+ Possible reasons why spikes can occur:
1656
+
1657
+ . Your application is busy processing a request that takes a very long time.
1658
+ If this is the case, then you might want to turn
1659
+ <<PassengerUseGlobalQueue,global queuing>> on.
1660
+ . Your application is frozen, i.e. has stopped responding. See
1661
+ <<debugging_frozen,Debugging frozen applications>> for tips.
1662
+
1663
+
1664
+ [[debugging_frozen]]
1665
+ === Debugging frozen applications ===
1666
+
1667
+ If one of your application instances is frozen (stopped responding), then you
1668
+ can figure out where it is frozen by killing it with 'SIGABRT'. This will cause the
1669
+ application to raise an exception, with a backtrace.
1670
+
1671
+ The exception (with full backtrace information) is normally logged into the Apache
1672
+ error log. But if your application or if its web framework has its own exception logging
1673
+ routines, then exceptions might be logged into the application's log files instead.
1674
+ This is the case with Ruby on Rails. So if you kill a Ruby on Rails application with
1675
+ 'SIGABRT', please check the application's 'production.log' first (assuming that you're
1676
+ running it in a 'production' environment). If you don't see a backtrace there, check
1677
+ the Apache error log.
1678
+
1679
+ NOTE: It is safe to kill application instances, even in live environments. Phusion Passenger
1680
+ will restart killed application instances, as if nothing bad happened.
1681
+
1682
+
1683
+ == Tips ==
1684
+
1685
+ [[user_switching]]
1686
+ === User switching (security) ===
1687
+
1688
+ There is a problem that plagues most PHP web hosts, namely the fact that all PHP
1689
+ applications are run in the same user context as the web server. So for
1690
+ example, Joe's PHP application will be able to read Jane's PHP application's
1691
+ passwords. This is obviously undesirable on many servers.
1692
+
1693
+ Phusion Passenger solves this problem by implementing 'user switching'. A Rails
1694
+ application is started as the owner of the file 'config/environment.rb',
1695
+ and a Rack application is started as the owner of the file 'config.ru'.
1696
+ So if '/home/webapps/foo/config/environment.rb' is owned by 'joe', then Phusion
1697
+ Passenger will launch the corresponding Rails application as 'joe' as well.
1698
+
1699
+ This behavior is the default, and you don't need to configure anything. But
1700
+ there are things that you should keep in mind:
1701
+
1702
+ - The owner of 'environment.rb' must have read access to the Rails application's
1703
+ folder, and read/write access to the Rails application's 'logs' folder.
1704
+ Likewise, the owner of 'config.ru' must have read access to the Rack application's
1705
+ folder.
1706
+ - This feature is only available if Apache is started by 'root'. This is the
1707
+ case on most Apache installations.
1708
+ - Under no circumstances will applications be run as 'root'. If
1709
+ 'environment.rb'/'config.ru' is owned as root or by an unknown user, then the
1710
+ Rails/Rack application will run as the user specified by
1711
+ <<PassengerDefaultUser,PassengerDefaultUser>>.
1712
+
1713
+ User switching can be disabled with the
1714
+ <<PassengerUserSwitching,PassengerUserSwitching>> option.
1715
+
1716
+
1717
+ [[reducing_memory_usage]]
1718
+ === Reducing memory consumption of Ruby on Rails applications by 33% ===
1719
+
1720
+ Is it possible to reduce memory consumption of your Rails applications by 33% on average,
1721
+ by using http://www.rubyenterpriseedition.com/[Ruby Enterprise Edition].
1722
+ Please visit the website for details.
1723
+
1724
+ Note that this feature does not apply to Rack applications.
1725
+
1726
+ [[capistrano]]
1727
+ === Capistrano recipe ===
1728
+
1729
+ Phusion Passenger can be combined with link:http://capify.org/[Capistrano].
1730
+ The following Capistrano recipe demonstrates Phusion Passenger support.
1731
+ It assumes that you're using Git as version control system.
1732
+
1733
+ --------------------------------------------------
1734
+ set :application, "myapp"
1735
+ set :domain, "example.com"
1736
+ set :repository, "ssh://#{domain}/path-to-your-git-repo/#{application}.git"
1737
+ set :use_sudo, false
1738
+ set :deploy_to, "/path-to-your-web-app-directory/#{application}"
1739
+ set :scm, "git"
1740
+
1741
+ role :app, domain
1742
+ role :web, domain
1743
+ role :db, domain, :primary => true
1744
+
1745
+ namespace :deploy do
1746
+ task :start, :roles => :app do
1747
+ run "touch #{current_release}/tmp/restart.txt"
1748
+ end
1749
+
1750
+ task :stop, :roles => :app do
1751
+ # Do nothing.
1752
+ end
1753
+
1754
+ desc "Restart Application"
1755
+ task :restart, :roles => :app do
1756
+ run "touch #{current_release}/tmp/restart.txt"
1757
+ end
1758
+ end
1759
+ --------------------------------------------------
1760
+
1761
+ You may notice that after each deploy, a new spawner server is
1762
+ created (it'll show up in `passenger-memory-stats`). Indeed, Capistrano will deploy
1763
+ to a path ending with '/current' (ie : '/u/apps/yourapp/current'), so that you don't
1764
+ have to care about revisions in your virtual host configuration. This '/current' directory
1765
+ is a symlink to the current revision deployed ('/path_to_app/releases/date_of_the_release').
1766
+ Phusion Passenger recognizes applications by their full canonical path, so after
1767
+ deploying a new version, Phusion Passenger will think that the new version is
1768
+ a totally different application, thereby creating a new spawner server:
1769
+
1770
+ --------------------------------------------------
1771
+ 1001 30291 [...] Passenger ApplicationSpawner: /u/apps/my_app/releases/20080509104413
1772
+ 1001 31371 [...] Passenger ApplicationSpawner: /u/apps/my_app/releases/20080509104632
1773
+ --------------------------------------------------
1774
+
1775
+ Don't worry about this. The (old) spawner server will terminate itself after its
1776
+ timeout period (10 minutes by default), so you will not run out of memory.
1777
+
1778
+ If you really want to release the spawner server's memory immediately, then you can add a command
1779
+ to your Capistrano script to terminate the Passenger spawn server after each deploy. That
1780
+ command is as follows:
1781
+
1782
+ --------------------------------------------------
1783
+ kill $( passenger-memory-stats | grep 'Passenger spawn server' | awk '{ print $1 }' )
1784
+ --------------------------------------------------
1785
+
1786
+ Killing the spawn server is completely safe, because Phusion Passenger will restart the
1787
+ spawn server if it has been terminated.
1788
+
1789
+
1790
+ === Moving Phusion Passenger to a different directory ===
1791
+
1792
+ It is possible to relocate the Phusion Passenger files to a different directory. It
1793
+ involves two steps:
1794
+
1795
+ 1. Moving the directory.
1796
+ 2. Updating the ``PassengerRoot'' configuration option in Apache.
1797
+
1798
+ For example, if Phusion Passenger is located in '/opt/passenger/', and you'd like to
1799
+ move it to '/usr/local/passenger/', then do this:
1800
+
1801
+ 1. Run the following command:
1802
+ +
1803
+ ------------------------------------
1804
+ mv /opt/passenger /usr/local/passenger
1805
+ ------------------------------------
1806
+ 2. Edit your Apache configuration file, and set:
1807
+ +
1808
+ ------------------------------------
1809
+ PassengerRoot /usr/local/passenger
1810
+ ------------------------------------
1811
+
1812
+ === Installing multiple Ruby on Rails versions ===
1813
+
1814
+ Each Ruby on Rails applications that are going to be deployed may require a
1815
+ specific Ruby on Rails version. You can install a specific version with
1816
+ this command:
1817
+ -----------------------------
1818
+ gem install rails -v X.X.X
1819
+ -----------------------------
1820
+ where 'X.X.X' is the version number of Ruby on Rails.
1821
+
1822
+ All of these versions will exist in parallel, and will not conflict with each
1823
+ other. Phusion Passenger will automatically make use of the correct version.
1824
+
1825
+ === X-Sendfile support ===
1826
+
1827
+ Phusion Passenger does not provide X-Sendfile support by itself. Please install
1828
+ link:http://tn123.ath.cx/mod_xsendfile/[mod_xsendfile] for X-Sendfile support.
1829
+
1830
+ === Upload progress ===
1831
+
1832
+ Phusion Passenger does not provide upload progress support by itself. Please
1833
+ try drogus's link:http://github.com/drogus/apache-upload-progress-module/tree/master[
1834
+ Apache upload progress module] instead.
1835
+
1836
+ === Making the application restart after each request ===
1837
+
1838
+ In some situations it might be desirable to restart the web application after
1839
+ each request, for example when developing a non-Rails application that doesn't
1840
+ support code reloading, or when developing a web framework.
1841
+
1842
+ To achieve this, simply create the file 'tmp/always_restart.txt' in your
1843
+ application's root folder. Unlike 'restart.txt', Phusion Passenger does not
1844
+ delete this file. If both files are present ('restart.txt' and 'always_restart.txt'),
1845
+ then Phusion Passenger will still restart the application, but won't delete
1846
+ 'restart.txt'.
1847
+
1848
+ NOTE: If you're just developing a Rails application then you probably don't need
1849
+ this feature. If you set 'RailsEnv development' in your Apache configuration,
1850
+ then Rails will automatically reload your application code after each request.
1851
+ 'always_restart.txt' is only useful if you're working on Ruby on Rails itself,
1852
+ or when you're not developing a Rails application and your web framework
1853
+ does not support code reloading.
1854
+
1855
+ == Appendix A: About this document ==
1856
+
1857
+ The text of this document is licensed under the
1858
+ link:http://creativecommons.org/licenses/by-sa/3.0/[Creative Commons
1859
+ Attribution-Share Alike 3.0 Unported License].
1860
+
1861
+ image:images/by_sa.png[link="http://creativecommons.org/licenses/by-sa/3.0/"]
1862
+
1863
+ Phusion Passenger is brought to you by link:http://www.phusion.nl/[Phusion].
1864
+
1865
+ image:images/phusion_banner.png[link="http://www.phusion.nl/"]
1866
+
1867
+ Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
1868
+
1869
+ == Appendix B: Terminology ==
1870
+
1871
+ [[application_root]]
1872
+ === Application root ===
1873
+ The root directory of an application that's served by Phusion Passenger.
1874
+
1875
+ In case of Ruby on Rails applications, this is the directory that contains
1876
+ 'Rakefile', 'app/', 'config/', 'public/', etc. In other words, the directory
1877
+ pointed to by `RAILS_ROOT`. For example, take the following directory structure:
1878
+
1879
+ -----------------------------------------
1880
+ /apps/foo/ <------ This is the Rails application's application root!
1881
+ |
1882
+ +- app/
1883
+ | |
1884
+ | +- controllers/
1885
+ | |
1886
+ | +- models/
1887
+ | |
1888
+ | +- views/
1889
+ |
1890
+ +- config/
1891
+ | |
1892
+ | +- environment.rb
1893
+ | |
1894
+ | +- ...
1895
+ |
1896
+ +- public/
1897
+ | |
1898
+ | +- ...
1899
+ |
1900
+ +- ...
1901
+ -----------------------------------------
1902
+
1903
+ In case of Rack applications, this is the directory that contains 'config.ru'.
1904
+ For example, take the following directory structure:
1905
+
1906
+ -----------------------------------------
1907
+ /apps/bar/ <----- This is the Rack application's application root!
1908
+ |
1909
+ +- public/
1910
+ | |
1911
+ | +- ...
1912
+ |
1913
+ +- config.ru
1914
+ |
1915
+ +- ...
1916
+ -----------------------------------------
1917
+
1918
+ In case of Python (WSGI) applications, this is the directory that contains
1919
+ 'passenger_wsgi.py'. For example, take the following directory structure:
1920
+
1921
+ -----------------------------------------
1922
+ /apps/baz/ <----- This is the WSGI application's application root!
1923
+ |
1924
+ +- public/
1925
+ | |
1926
+ | +- ...
1927
+ |
1928
+ +- passenger_wsgi.py
1929
+ |
1930
+ +- ...
1931
+ -----------------------------------------
1932
+
1933
+
1934
+ [[spawning_methods_explained]]
1935
+ == Appendix C: Spawning methods explained ==
1936
+
1937
+ At its core, Phusion Passenger is an HTTP proxy and process manager. It spawns
1938
+ Ruby on Rails/Rack/WSGI worker processes (which may also be referred to as
1939
+ 'backend processes'), and forwards incoming HTTP request to one of the worker
1940
+ processes.
1941
+
1942
+ While this may sound simple, there's not just one way to spawn worker processes.
1943
+ Let's go over the different spawning methods. For simplicity's sake, let's
1944
+ assume that we're only talking about Ruby on Rails applications.
1945
+
1946
+ === The most straightforward and traditional way: conservative spawning ===
1947
+
1948
+ Phusion Passenger could create a new Ruby process, which will then load the
1949
+ Rails application along with the entire Rails framework. This process will then
1950
+ enter an request handling main loop.
1951
+
1952
+ This is the most straightforward way to spawn worker processes. If you're
1953
+ familiar with the Mongrel application server, then this approach is exactly
1954
+ what mongrel_cluster performs: it creates N worker processes, each which loads
1955
+ a full copy of the Rails application and the Rails framework in memory. The Thin
1956
+ application server employs pretty much the same approach.
1957
+
1958
+ Note that Phusion Passenger's version of conservative spawning differs slightly
1959
+ from mongrel_cluster. Mongrel_cluster creates entirely new Ruby processes. In
1960
+ programmers jargon, mongrel_cluster creates new Ruby processes by forking the
1961
+ current process and exec()-ing a new Ruby interpreter. Phusion Passenger on the
1962
+ other hand creates processes that reuse the already loaded Ruby interpreter. In
1963
+ programmers jargon, Phusion Passenger calls fork(), but not exec().
1964
+
1965
+ === The smart spawning method ===
1966
+
1967
+ NOTE: Smart spawning is only available for Ruby on Rails applications, not for
1968
+ Rack applications or WSGI applications.
1969
+
1970
+ While conservative spawning works well, it's not as efficient as it could be
1971
+ because each worker process has its own private copy of the Rails application
1972
+ as well as the Rails framework. This wastes memory as well as startup time.
1973
+
1974
+ image:images/conservative_spawning.png[Worker processes and conservative spawning] +
1975
+ 'Figure: Worker processes and conservative spawning. Each worker process has its
1976
+ own private copy of the application code and Rails framework code.'
1977
+
1978
+ It is possible to make the different worker processes share the memory occupied
1979
+ by application and Rails framework code, by utilizing so-called
1980
+ copy-on-write semantics of the virtual memory system on modern operating
1981
+ systems. As a side effect, the startup time is also reduced. This is technique
1982
+ is exploited by Phusion Passenger's 'smart' and 'smart-lv2' spawn methods.
1983
+
1984
+ ==== How it works ====
1985
+
1986
+ When the 'smart-lv2' spawn method is being used, Phusion Passenger will first
1987
+ create a so-called 'ApplicationSpawner server' process. This process loads the
1988
+ entire Rails application along with the Rails framework, by loading
1989
+ 'environment.rb'. Then, whenever Phusion Passenger needs a new worker process,
1990
+ it will instruct the ApplicationSpawner server to do so. The ApplicationSpawner
1991
+ server will create a worker new process
1992
+ that reuses the already loaded Rails application/framework. Creating a worker
1993
+ process through an already running ApplicationSpawner server is very fast, about
1994
+ 10 times faster than loading the Rails application/framework from scratch. If
1995
+ the Ruby interpreter is copy-on-write friendly (that is, if you're running
1996
+ <<reducing_memory_usage,Ruby Enterprise Edition>>) then all created worker
1997
+ processes will share as much common
1998
+ memory as possible. That is, they will all share the same application and Rails
1999
+ framework code.
2000
+
2001
+ image:images/smart-lv2.png[] +
2002
+ 'Figure: Worker processes and the smart-lv2 spawn method. All worker processes,
2003
+ as well as the ApplicationSpawner, share the same application code and Rails
2004
+ framework code.'
2005
+
2006
+ The 'smart' spawn method goes even further, by caching the Rails framework in
2007
+ another process called the 'FrameworkSpawner server'. This process only loads
2008
+ the Rails framework, not the application. When a FrameworkSpawner server is
2009
+ instructed to create a new worker process, it will create a new
2010
+ ApplicationSpawner to which the instruction will be delegated. All those
2011
+ ApplicationSpawner servers, as well as all worker processes created by those
2012
+ ApplicationSpawner servers, will share the same Rails framework code.
2013
+
2014
+ The 'smart-lv2' method allows different worker processes that belong to the same
2015
+ application to share memory. The 'smart' method allows different worker
2016
+ processes - that happen to use the same Rails version - to share memory, even if
2017
+ they don't belong to the same application.
2018
+
2019
+ Notes:
2020
+
2021
+ - Vendored Rails frameworks cannot be shared by different applications, even if
2022
+ both vendored Rails frameworks are the same version. So for efficiency reasons
2023
+ we don't recommend vendoring Rails.
2024
+ - ApplicationSpawner and FrameworkSpawner servers have an idle timeout just
2025
+ like worker processes. If an ApplicationSpawner/FrameworkSpawner server hasn't
2026
+ been instructed to do anything for a while, it will be shutdown in order to
2027
+ conserve memory. This idle timeout is configurable.
2028
+
2029
+ ==== Summary of benefits ====
2030
+
2031
+ Suppose that Phusion Passenger needs a new worker process for an application
2032
+ that uses Rails 2.2.1.
2033
+
2034
+ - If the 'smart-lv2' spawning method is used, and an ApplicationSpawner server
2035
+ for this application is already running, then worker process creation time is
2036
+ about 10 times faster than conservative spawning. This worker process will also
2037
+ share application and Rails framework code memory with the ApplicationSpawner
2038
+ server and the worker processes that had been spawned by this ApplicationSpawner
2039
+ server.
2040
+ - If the 'smart' spawning method is used, and a FrameworkSpawner server for
2041
+ Rails 2.2.1 is already running, but no ApplicationSpawner server for this
2042
+ application is running, then worker process creation time is about 2 times
2043
+ faster than conservative spawning. If there is an ApplicationSpawner server
2044
+ for this application running, then worker process creation time is about 10
2045
+ times faster. This worker process will also share application and Rails
2046
+ framework code memory with the ApplicationSpawner and FrameworkSpawner
2047
+ servers.
2048
+
2049
+ You could compare ApplicationSpawner and FrameworkSpawner servers with stem
2050
+ cells, that have the ability to quickly change into more specific cells (worker
2051
+ process).
2052
+
2053
+ In practice, the smart spawning methods could mean a memory saving of about 33%,
2054
+ assuming that your Ruby interpreter is <<reducing_memory_usage,copy-on-write friendly>>.
2055
+
2056
+ Of course, smart spawning is not without gotchas. But if you understand the
2057
+ gotchas you can easily reap the benefits of smart spawning.
2058
+
2059
+ === Smart spawning gotcha #1: unintential file descriptor sharing ===
2060
+
2061
+ Because worker processes are created by forking from an ApplicationSpawner
2062
+ server, it will share all file descriptors that are opened by the
2063
+ ApplicationSpawner server. (This is part of the semantics of the Unix
2064
+ 'fork()' system call. You might want to Google it if you're not familiar with
2065
+ it.) A file descriptor is a handle which can be an opened file, an opened socket
2066
+ connection, a pipe, etc. If different worker processes write to such a file
2067
+ descriptor at the same time, then their write calls will be interleaved, which
2068
+ may potentially cause problems.
2069
+
2070
+ The problem commonly involves socket connections that are unintentially being
2071
+ shared. You can fix it by closing and reestablishing the connection when Phusion
2072
+ Passenger is creating a new worker process. Phusion Passenger provides the API
2073
+ call `PhusionPassenger.on_event(:starting_worker_process)` to do so. So you
2074
+ could insert the following code in your 'environment.rb':
2075
+
2076
+ [source, ruby]
2077
+ -----------------------------------------
2078
+ if defined?(PhusionPassenger)
2079
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
2080
+ if forked
2081
+ # We're in smart spawning mode.
2082
+ ... code to reestablish socket connections here ...
2083
+ else
2084
+ # We're in conservative spawning mode. We don't need to do anything.
2085
+ end
2086
+ end
2087
+ end
2088
+ -----------------------------------------
2089
+
2090
+ Note that Phusion Passenger automatically reestablishes the connection to the
2091
+ database upon creating a new worker process, which is why you normally do not
2092
+ encounter any database issues when using smart spawning mode.
2093
+
2094
+ ==== Example 1: Memcached connection sharing (harmful) ====
2095
+
2096
+ Suppose we have a Rails application that connects to a Memcached server in
2097
+ 'environment.rb'. This causes the ApplicationSpawner to have a socket connection
2098
+ (file descriptor) to the Memcached server, as shown in the following figure:
2099
+
2100
+ +--------------------+
2101
+ | ApplicationSpawner |-----------[Memcached server]
2102
+ +--------------------+
2103
+
2104
+ Phusion Passenger then proceeds with creating a new Rails worker process, which
2105
+ is to process incoming HTTP requests. The result will look like this:
2106
+
2107
+ +--------------------+
2108
+ | ApplicationSpawner |------+----[Memcached server]
2109
+ +--------------------+ |
2110
+ |
2111
+ +--------------------+ |
2112
+ | Worker process 1 |-----/
2113
+ +--------------------+
2114
+
2115
+ Since a 'fork()' makes a (virtual) complete copy of a process, all its file
2116
+ descriptors will be copied as well. What we see here is that ApplicationSpawner
2117
+ and Worker process 1 both share the same connection to Memcached.
2118
+
2119
+ Now supposed that your site gets Slashdotted and Phusion Passenger needs to
2120
+ spawn another worker process. It does so by forking ApplicationSpawner. The
2121
+ result is now as follows:
2122
+
2123
+ +--------------------+
2124
+ | ApplicationSpawner |------+----[Memcached server]
2125
+ +--------------------+ |
2126
+ |
2127
+ +--------------------+ |
2128
+ | Worker process 1 |-----/|
2129
+ +--------------------+ |
2130
+ |
2131
+ +--------------------+ |
2132
+ | Worker process 2 |-----/
2133
+ +--------------------+
2134
+
2135
+ As you can see, Worker process 1 and Worker process 2 have the same Memcache
2136
+ connection.
2137
+
2138
+ Suppose that users Joe and Jane visit your website at the same time. Joe's
2139
+ request is handled by Worker process 1, and Jane's request is handled by Worker
2140
+ process 2. Both worker processes want to fetch something from Memcached. Suppose
2141
+ that in order to do that, both handlers need to send a "FETCH" command to Memcached.
2142
+
2143
+ But suppose that, after worker process 1 having only sent "FE", a context switch
2144
+ occurs, and worker process 2 starts sending a "FETCH" command to Memcached as
2145
+ well. If worker process 2 succeeds in sending only one bye, 'F', then Memcached
2146
+ will receive a command which begins with "FEF", a command that it does not
2147
+ recognize. In other words: the data from both handlers get interleaved. And thus
2148
+ Memcached is forced to handle this as an error.
2149
+
2150
+ This problem can be solved by reestablishing the connection to Memcached after forking:
2151
+
2152
+ +--------------------+
2153
+ | ApplicationSpawner |------+----[Memcached server]
2154
+ +--------------------+ | |
2155
+ | |
2156
+ +--------------------+ | |
2157
+ | Worker process 1 |-----/| |
2158
+ +--------------------+ | | <--- created this
2159
+ X | new
2160
+ | connection
2161
+ X <-- closed this |
2162
+ +--------------------+ | old |
2163
+ | Worker process 2 |-----/ connection |
2164
+ +--------------------+ |
2165
+ | |
2166
+ +-------------------------------------+
2167
+
2168
+ Worker process 2 now has its own, separate communication channel with Memcached.
2169
+ The code in 'environment.rb' looks like this:
2170
+
2171
+ [source, ruby]
2172
+ -----------------------------------------
2173
+ if defined?(PhusionPassenger)
2174
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
2175
+ if forked
2176
+ # We're in smart spawning mode.
2177
+ reestablish_connection_to_memcached
2178
+ else
2179
+ # We're in conservative spawning mode. We don't need to do anything.
2180
+ end
2181
+ end
2182
+ end
2183
+ -----------------------------------------
2184
+
2185
+ ==== Example 2: Log file sharing (not harmful) ====
2186
+
2187
+ There are also cases in which unintential file descriptor sharing is not harmful.
2188
+ One such case is log file file descriptor sharing. Even if two processes write
2189
+ to the log file at the same time, the worst thing that can happen is that the
2190
+ data in the log file is interleaved.
2191
+
2192
+ To guarantee that the data written to the log file is never interleaved, you
2193
+ must synchronize write access via an inter-process synchronization mechanism,
2194
+ such as file locks. Reopening the log file, like you would have done in the
2195
+ Memcached example, doesn't help.
2196
+
2197
+ === Smart spawning gotcha #2: the need to revive threads ===
2198
+
2199
+ Another part of the 'fork()' system call's semantics is the fact that threads
2200
+ disappear after a fork call. So if you've created any threads in environment.rb,
2201
+ then those threads will no longer be running in newly created worker process.
2202
+ You need to revive them when a new worker process is created. Use the
2203
+ `:starting_worker_process` event that Phusion Passenger provides, like this:
2204
+
2205
+ [source, ruby]
2206
+ -----------------------------------------
2207
+ if defined?(PhusionPassenger)
2208
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
2209
+ if forked
2210
+ # We're in smart spawning mode.
2211
+ ... code to revive threads here ...
2212
+ else
2213
+ # We're in conservative spawning mode. We don't need to do anything.
2214
+ end
2215
+ end
2216
+ end
2217
+ -----------------------------------------
2218
+
2219
+ === Smart spawning gotcha #3: code load order ===
2220
+
2221
+ This gotcha is only applicable to the 'smart' spawn method, not the 'smart-lv2'
2222
+ spawn method.
2223
+
2224
+ If your application expects the Rails framework to be not loaded during the
2225
+ beginning of 'environment.rb', then it can cause problems when an
2226
+ ApplicationSpawner is created from a FrameworkSpawner, which already has the
2227
+ Rails framework loaded. The most common case is when applications try to patch
2228
+ Rails by dropping a modified file that has the same name as Rails's own file,
2229
+ in a path that comes earlier in the Ruby search path.
2230
+
2231
+ For example, suppose that we have an application which has a patched version
2232
+ of 'active_record/base.rb' located in 'RAILS_ROOT/lib/patches', and
2233
+ 'RAILS_ROOT/lib/patches' comes first in the Ruby load path. When conservative
2234
+ spawning is used, the patched version of 'base.rb' is properly loaded. When
2235
+ 'smart' (not 'smart-lv2') spawning is used, the original 'base.rb' is used
2236
+ because it was already loaded, so a subsequent `require "active_record/base"`
2237
+ has no effect.