如何部署 Ruby 应用
Flynn 支持多种 Ruby 解释器来实现对 Ruby,Rack,Rails 等类型应用的支持,如:MRI, JRuby,Rubinius。
Flynn 使用 Heroku Ruby 构建包来实现 Ruby 应用的检测,编译和发布。
应用检测
Flynn 通过检测根目录下的Gemfile
文件来确定这是 Ruby 应用。通过 Bundler(一个 Ruby 的软件包管理工具)来检测,下载,安装应用所依赖的软件包。
软件依赖
Gems
Gemfile
文件的主要用途是用来管理软件包的依赖关系。下面是Gemfile
文件的一个示例,其中部署的 Ruby 应用依赖 rack
:
source "https://rubygems.org"
gem "rack"
在应用中附上上述 Gemfile
后,应该运行bundle install
来安装所需的软件包,这样会保存所有软件包内容和版本的快照到本地的Gemfile.lock
文件。
在 Flynn 中部署 Ruby 应用时,必须通过 Gemfile.lock
文件来确定哪些依赖的软件包需要安装。如果没有这个文件,部署将会失败。
关于Gemfile
文件格式的详细信息,请参见:Gemfile 页面。
具体环境
可能有些 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 安装页。
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 基础软件包页面。
应用类型
在应用根目录下的 Procfile
里声明应用的类型,格式:TYPE:COMMAND
。如果没有Procfile
,Flynn 会指定一个默认的应用类型(参见下文开发框架检测获取更多信息)。
下面是一些常见的应用类型:
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
软件包提供了一个好用的 DSL ,可以按如下声明其应用类型:
clock: bundle exec clockwork lib/clock.rb
其中lib/clock.rb
里包含 Clockwork 声明。
本地测试
如果想在本地测试应用的类型,需要安装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
的详细信息,请参见命令行文档。