如何部署 Ruby 应用 #如何部署 Ruby 应用 Flynn 支持多种 Ruby 解释器来实现对 Ruby,Rack,Rails 等类型应用的支持,如:MRI, [JRuby](http://www.jruby.org/),[Rubinius](http://rubini.us/)。 Flynn 使用 [Heroku Ruby 构建包](https://github.com/heroku/heroku-buildpack-ruby)来实现 Ruby 应用的检测,编译和发布。 ##应用检测 Flynn 通过检测根目录下的`Gemfile`文件来确定这是 Ruby 应用。通过 [Bundler](https://bundler.io/)(一个 Ruby 的软件包管理工具)来检测,下载,安装应用所依赖的软件包。 ##软件依赖 ###Gems `Gemfile`文件的主要用途是用来管理软件包的依赖关系。 下面是`Gemfile`文件的一个示例,其中部署的 Ruby 应用依赖 `rack`: source "https://rubygems.org" gem "rack" 在应用中附上上述 `Gemfile`后,应该运行`bundle install`来安装所需的软件包,这样会保存所有软件包内容和版本的快照到本地的`Gemfile.lock`文件。 在 Flynn 中部署 Ruby 应用时,必须通过 `Gemfile.lock`文件来确定哪些依赖的软件包需要安装。**如果没有这个文件,部署将会失败。** *关于`Gemfile`文件格式的详细信息,请参见:[Gemfile 页面](http://bundler.io/gemfile.html)。* ####具体环境 可能有些 gems 只会在本地开发的时候用到,当部署到生产系统里时不需要。 这可以在Flynn 调用 `bundle install`时,使用`--withoutdevelopment:test`参数,这样在部署时就会跳过`Gemfile`里的`development`和`test`组的内容。 例如,你可能在本地开发时用到`debugger`和`rspc`,但在真正部署时很少需要,你可以将其放到上述组中: group :development do gem "debugger" end group :test do gem "rspec" end 针对上面的配置,下面是 Flynn 将会运行的完整命令: bundle install \ --without development:test \ --path vendor/bundle \ --binstubs vendor/bundle/bin \ -j4 \ --deployment \ --no-clean *关于`bundle install`的详细信息,请参见 [bundle 安装页](http://bundler.io/bundle_install.html)。* ###Ruby 解释器 如果应用需要特定的 Ruby 解释器,可以在`Gemfile`里指定。 使用 MRI v2.1.2: ruby "2.1.2" 使用 JRuby 1.7.16 ,带 Ruby 2.0 支持: ruby "2.0.0", engine: "jruby", engine_version: "1.7.16" 使用 Rubinius 2.2.10,带 Ruby 2.1 支持: ruby "2.1.0", engine: "rbx", engine_version: "2.2.10" ##原生扩展库 应用构建及运行时所在的容器包含了一些预安装的本地库,可用于编译 Ruby 应用的原生扩展,例如: * `libssl-dev` * `libmysqlclient-dev` * `libxml2-dev` * `libxslt-dev` *库文件的完整列表,参见:[Dockfile 基础软件包页面](https://github.com/flynn/flynn/blob/master/util/cedarish/Dockerfile)。 * ##应用类型 在应用根目录下的 `Procfile` 里声明应用的类型,格式:`TYPE:COMMAND`。 如果没有`Procfile`,Flynn 会指定一个默认的应用类型(参见下文[开发框架检测](https://flynn.io/docs/how-to-deploy-ruby#framework-detection)获取更多信息)。 下面是一些常见的应用类型: ###web `web`类型的应用会包含 HTTP 路由和通信的端口设置,通常会启动一个 HTTP 服务器,常见的配置: **Thin** web: bundle exec thin start -p $PORT -e $RACK_ENV **Unicorn** web: bundle exec -p $PORT -c config/unicorn.rb **Puma** web: bundle exec puma -C config/puma.rb *注意:如果使用 Puma,确认在`config/puma.rb`里配置了`ENV[PORT]`端口变量。* ###worker `worker`类型的应用通常是在后台运行的进程,用来处理队列任务,例如: **Resque** worker: QUEUE=* bundle exec rake resque:work **Sidekiq** worker: bundle exec sidekiq **Delayed::Job** worker: bundle exec delayed_job start ###clock `clock`类型的应用,通常用来按特定的周期执行定时(cron-like)任务。 `[Clockwork](https://github.com/tomykaira/clockwork)`软件包提供了一个好用的 DSL ,可以按如下声明其应用类型: clock: bundle exec clockwork lib/clock.rb 其中`lib/clock.rb`里包含 Clockwork 声明。 ##本地测试 如果想在本地测试应用的类型,需要安装`[Foreman](https://github.com/ddollar/foreman)`,同时在根目录下的`.env`文件里设置必要的环境变量(例如:`PORT=5000`),启动 Foreman: $ foreman start 14:25:33 web.1 | started with pid 42868 14:25:33 worker.1 | started with pid 42869 14:25:33 clock.1 | started with pid 42870 14:25:34 web.1 | == Sinatra/1.4.5 has taken the stage on 5000 for development with backup from Thin 14:25:34 web.1 | Thin web server (v1.6.3 codename Protein Powder) 14:25:34 web.1 | Maximum connections set to 1024 14:25:34 web.1 | Listening on localhost:5000, CTRL+C to stop 14:25:34 clock.1 | I, [2014-10-24T14:25:34.729860 #42870] INFO -- : Starting clock for 1 events: [ frequent.job ] 14:25:34 clock.1 | I, [2014-10-24T14:25:34.729999 #42870] INFO -- : Triggering 'frequent.job' 14:25:34 clock.1 | Running frequent.job ... ##开发框架检测 不同的 Ruby 开发框架会有不同的配置,Flynn 可以检测在用的框架,并按需配置。 下面是 Flynn 检测常见框架的规则,并设置默认的应用类型(当`Procfile`文件没有声明应用类型时): ###Ruby 应用根目录下的`Gemfile`表明这是一个 Ruby 应用。 配置默认应用类型: rake: bundle exec rake console: bundle exec irb ###Rack 在`Gemfile.lock`里包含`rack`包,表明这是一个 Rack 应用。 配置默认应用类型: web: bundle exec rackup config.ru -p $PORT rake: bundle exec rake console: bundle exec irb ###Rails 2 在`Gemfile.lock`里包含`rails`,版本大于等于2.0.0,并且小于 3.0.0,表明这是一个 Rail 2 应用。 配置默认应用类型: web: bundle exec ruby script/server -p $PORT worker: bundle exec rake jobs:work rake: bundle exec rake console: bundle exec script/console ###Rails 3 在`Gemfile.lock`里包含`rails`,版本大于等于3.0.0,并且小于 4.0.0,表明这是一个 Rail 3 应用。 配置默认应用类型: web: bundle exec rails server -p $PORT worker: bundle exec rake jobs:work rake: bundle exec rake console: bundle exec rails console ###Rails 4 在`Gemfile.lock`里包含`rails`,版本大于等于4.0.0,并且小于 5.0.0,表明这是一个 Rail 4 应用。 配置默认应用类型: web: bin/rails server -p $PORT -e $RAILS_ENV worker: bundle exec rake jobs:work rake: bundle exec rake console: bin/rails console ##Assets Flynn 会在应用编译的最后阶段运行自定义的`assets:precompile`任务。 如果 Flynn 检测到 Rails 3 或 4 的应用,但`Gemfile`里没有包含`rails_12factor`,系统会自动安装`rails3_serve_static_assets`并且配置`config.serve_static_assets = true`。这样你的应用才能在`public`目录里,对外发布这些资源。 ##执行任务 如果需要运行 Rake 任务,或者在应用里打开 Rails 终端,使用`Flynn run`。例如: $ flynn run rake db:migrate $ flynn run rails console *关于`flynn run`的详细信息,请参见[命令行文档](https://flynn.io/docs/cli#run)。*