aaron67's log

在Ubuntu Server 16.04上配置Apache和Passenger(mod_rails)部署Sinatra应用

Phusion Passenger是什么?

  • 开始被设计成Apache的module,用来部署Rails,叫mod_rails
  • 后来不断发展成独立的Ruby Web Server,改名Passenger

关于Passenger的一些历史

Sinatra是一个基于Ruby的DSL,方便开发者快速创建Web应用。官方文档里有更详细的说明

Hello Sinatra

$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
...
$ \curl -sSL https://get.rvm.io | bash -s stable
...
$ rvm -v
rvm 1.28.0 (latest) by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]
  • 安装Ruby
$ rvm install 2.3.3
...
$ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]
  • 安装Sinatra
$ gem install sinatra
  • 码一段代码
$ vi hello_sinatra.rb
require 'sinatra'

get '/' do
  'Hello, Sinatra'
end
  • 运行
$ ruby hello_sinatra.rb 
[2017-02-13 01:32:47] INFO  WEBrick 1.3.1
[2017-02-13 01:32:47] INFO  ruby 2.3.3 (2016-11-21) [x86_64-linux]
== Sinatra (v1.4.8) has taken the stage on 4567 for development with backup from WEBrick
[2017-02-13 01:32:47] INFO  WEBrick::HTTPServer#start: pid=7962 port=4567
  • 访问localhost:4567,能看到输出Hello, Sinatra

配置Apache和Passenger

安装Apache

$ sudo apt-get install apache2

安装Passenger

按照官方网站上提供的安装向导,生成具体的安装步骤

  • relevant integration mode
    • Apache
    • Passenger open source
  • operating system / installation method
    • Debian, Ubuntu (With APT)
    • Ubuntu 16.04 LTS (Xenial)
# Step 1: install Passenger packages

## Install our PGP key and add HTTPS support for APT
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
$ sudo apt-get install -y apt-transport-https ca-certificates

## Add our APT repository
$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'
$ sudo apt-get update

## Install Passenger + Apache module
$ sudo apt-get install -y libapache2-mod-passenger

# Step 2: enable the Passenger Apache module and restart Apache

$ sudo a2enmod passenger
$ sudo apache2ctl restart

# Step 3: check installation

$ sudo /usr/bin/passenger-config validate-install
 * Checking whether this Phusion Passenger install is in PATH... ✓
 * Checking whether there are no other Phusion Passenger installations... ✓

$ sudo /usr/sbin/passenger-memory-stats
Version: 5.0.8
Date   : 2015-05-28 08:46:20 +0200

---------- Apache processes ----------
PID    PPID   VMSize    Private  Name
--------------------------------------
3918   1      190.1 MB  0.1 MB   /usr/sbin/apache2
...

----- Passenger processes ------
PID    VMSize    Private   Name
--------------------------------
12517  83.2 MB   0.6 MB    Passenger watchdog
12520  266.0 MB  3.4 MB    Passenger core
12531  149.5 MB  1.4 MB    Passenger ust-router
...

# Step 4: update regularly

$ sudo apt-get update
$ sudo apt-get upgrade

Sinatra部署文件夹

/var/www/下,新建hello-sinatra文件夹,结构如下

hello-sinatra/
├── config.ru
├── hello.rb
├── logs/
├── pids/
├── public/
└── tmp/
    └── restart.txt

hello.rb的内容

require 'sinatra/base'

class HelloSinatra < Sinatra::Base
  get '/' do
    'Hello, Sinatra'
  end
end

config.ru的内容

require File.expand_path('../hello.rb', __FILE__)
use Rack::ShowExceptions  # 访问未定义的路由时,在网页上显示异常信息
run HelloSinatra.new

配置Apache的vhost

/etc/apache2/sites-available下,拷贝一份默认的vhost模板

$ sudo cp 000-default.conf hello-sinatra.conf

/etc/apache2/sites-enabled下,新建一个符号链接到hello-sinatra.conf

$ sudo ln -s ../sites-available/hello-sinatra.conf .
$ sudo vi hello-sinatra.conf
<VirtualHost *:80>
    DocumentRoot /var/www/hello-sinatra/public  # !!

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    PassengerRuby /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby  # !!

    <Directory /var/www/hello-sinatra/public>  # !!
        Allow from all
        Options -MultiViews
    </Directory>
</VirtualHost>

两点注意

  • DocumentRootDirectory里的路径要写到public文件夹
  • PassengerRuby的值,通过下面的命令查看
$ passenger-config about ruby-command
passenger-config was invoked through the following Ruby interpreter:
  Command: /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby
  Version: ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]
  To use in Apache: PassengerRuby /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby  # <== 看这里
  To use in Nginx : passenger_ruby /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby
  To use with Standalone: /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby /usr/bin/passenger start

重启Apache服务

$ sudo service apache2 restart

测试

浏览器访问服务器地址,显示的是Apache默认的欢迎页面(位置在/var/www/html/index.html

这是由于000-default.confhello-sinatra.conf配置了不同的DocumentRoot,但没配置不同的ServerName

vhost配置文件 ServerName DocumentRoot
000-default.conf /var/www/html
hello-sinatra.conf /var/www/hello-sinatra

更多关于Apache Name-based Virtual Hosts的内容,可以阅读官方文档

测试用的虚拟机没有域名绑定,所以简单的直接关掉000-default.conf的vhost设置

$ sudo a2dissite 000-default
Site 000-default disabled.
To activate the new configuration, you need to run:
  service apache2 reload  # <== reload使配置生效

重新加载或者重启Apache服务使配置生效

一个错误

查看Apache的日志文件/var/log/apache2/error.log,刚才的访问会输出如下错误

App 9888 stdout:
App 9888 stderr:  [passenger_native_support.so] trying to compile for the current user (nobody) and Ruby interpreter...
App 9888 stderr:      (set PASSENGER_COMPILE_NATIVE_SUPPORT_BINARY=0 to disable)
App 9888 stderr:      Warning: compilation did not succeed. To learn why, read this file:
App 9888 stderr:      /tmp/passenger_native_support-1ozcjtk.log
App 9888 stderr:  [passenger_native_support.so] finding downloads for the current Ruby interpreter...
App 9888 stderr:      (set PASSENGER_DOWNLOAD_NATIVE_SUPPORT_BINARY=0 to disable)
App 9888 stderr:      # tar xzf rubyext-ruby-2.3.3-x86_64-linux.tar.gz
App 9888 stderr:      # rm -f rubyext-ruby-2.3.3-x86_64-linux.tar.gz
App 9888 stderr:      Checking whether downloaded binary is usable...
App 9888 stderr:      # /home/aaron67/.rvm/gems/ruby-2.3.3/wrappers/ruby -I. test.rb
App 9888 stderr:      Binary is usable.
App 9888 stderr:      # current user is: nobody
App 9888 stderr:      # mkdir -p /nonexistent/.passenger/native_support/5.1.2/ruby-2.3.3-x86_64-linux
App 9888 stderr:      Encountered permission error, but no more directories to try. Giving up.
App 9888 stderr:      -------------------------------
App 9888 stderr:  [passenger_native_support.so] will not be used (cannot compile or download)
App 9888 stderr:   --> Passenger will still operate normally.
App 9924 stdout:

看起来像是目录权限问题,修改/var/www/hello-sinatra文件夹的owner成自己

$ sudo chown -R aaron67:aaron67 /var/www/hello-sinatra/

重启服务,搞定

参考

如果你觉得文章不错,可以请我喝杯咖啡