Skip to content

Commit

Permalink
ch8 deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
xdite committed Nov 10, 2013
1 parent ca71660 commit 52499bc
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 29 deletions.
4 changes: 4 additions & 0 deletions manuscript/Book.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,9 @@ chapter-07.txt
chapter-07-1.txt
chapter-07-2.txt
chapter-07-3.txt
chapter-08.txt
chapter-08-1.txt
chapter-08-2.txt
chapter-08-3.txt
booklist.txt
extra.txt
6 changes: 3 additions & 3 deletions manuscript/chapter-06-2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ Helper 是一些使用在 Rails 的 View 當中,用 Ruby 產生/整理 HTML co
<%= @post.content %> %>
~~~~~~~~~

隨著專案變遷,這樣的程式碼,可能會依需求改成:

(需要內容斷行)
隨著專案變遷,這樣的程式碼,可能會依需求改成:(需要內容斷行)

~~~~~~~~~
<%= simple_format(@post.content) %> %>
Expand All @@ -48,6 +46,8 @@ Helper 是一些使用在 Rails 的 View 當中,用 Ruby 產生/整理 HTML co

而麻煩的是,這樣類似的內容,常常在專案出現。每當需求變更,開發者就需要去找出來,有十個地方,就需要改十遍,很是麻煩。

{::pagebreak :/}

Helper 就是用在這樣的地方。與其一開始寫下

~~~~~~~~~
Expand Down
4 changes: 3 additions & 1 deletion manuscript/chapter-06-3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ Helper 是一些使用在 Rails 的 View 當中,用 Ruby 產生/整理 HTML co
* vendor_js/disqus_js
* global/footer

本書範例 project 裡面的 layout/application.html.erb 就是很好的範例(見下頁)。


{::pagebreak :/}

本書範例 project 裡面的 layout/application.html.erb 就是很好的範例。

~~~~~~~~~
<%= render :partial => "common/menu" %>

Expand Down
4 changes: 4 additions & 0 deletions manuscript/chapter-06-4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class Post < ActiveRecord::Base
end
~~~~~~~~

{::pagebreak :/}

### Scope 串接

甚至也提供串接的功能:

~~~~~~~~
Expand Down
89 changes: 89 additions & 0 deletions manuscript/chapter-07-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{::pagebreak :/}

## Ch 7.1 Rake

Rake 的意思就是字面上直觀的 Ruby Make,Ruby 版 Make:用 Ruby 開發的 Build Tool。

你也許會問,Ruby 是直譯語言,不需要 compile,為何還需要 Build Tool。

與其說 Rake 是一套 Build Tool,還不如說是一套 task 管理工具。我們通常會使用 Ruby based 的 Rake 在 Rails 專案裡編寫 task。

### Rails 內的 rake tasks

`rake -T` 會秀出一大串這個 Rails project 可用的 rake tasks (包含 plugin 內建的 task 也會秀出來)。

~~~~~~~~
rake about # List versions of all Rails frameworks and the environment
rake assets:clean # Remove compiled assets
rake assets:precompile # Compile all the assets named in config.assets.precompile
rake db:create # Create the database from config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)
rake db:drop # Drops the database for the current Rails.env (use db:drop:all to drop all databases)
.....

~~~~~~~~


### 清空系統重跑 migration 與種子資料的 rake dev:build


在還未上線的開發階段,我們有時會不是那麼喜歡被 db migration 拘束,有時候下錯了 migration,或想直接清空系統重來,實在是件麻煩事。因此寫支 rake 檔自動化是個良招。

新增 `lib/tasks/dev.rake`

~~~~~~~~
namespace :dev do
desc "Rebuild system"
task :build => ["tmp:clear", "log:clear", "db:drop", "db:create", "db:migrate"] task :rebuild => [ "dev:build", "db:seed" ]
end
~~~~~~~~

執行 rake dev:build 看看會發生什麼事吧:

~~~~~~~~
$ rake dev:build
~~~~~~~~


`rake dev:build` 是個無敵大絕:清空系統重來!

不過系統清空重來還是很麻煩,我們還是需要一些種子資料,如種子看板,種子文章,管理者帳號,測試用一般帳號。


### rake db:seed

`db/seed.rb` 就是讓你撰寫這些種子資料,可以在專案開始時自動產生一些種子資料。


I> ## 注意
I>
I> 請注意!seed.rb 裡放的是種子資料!不是假資料!假資料應該要放在 rake 檔裡,而不是放在種子檔裡!
I>

~~~~~~~~

admin = User.new(:email => "[email protected]", :password => "123456",
:password_confirmation => "123456")
admin.is_admin = true
admin.save!

normal_user = User.new(:email => "[email protected]", :password => "123456",
:password_confirmation => "123456")
normal_user.save!

board = Board.create!(:name => "System Announcement")

post = board.posts.build(:title => "First Post", :content => "This is a demo post")
post.user_id = admin.id
post.save!

~~~~~~~~





X>## 練習作業
X>
X> * 撰寫一個 task 可以自動連續執行 rake db:drop ; rake db:create ; rake db:migrate ; rake db:seed
X> * 撰寫一個 task 可以執行 rake dev:fake 生假資料 ( 自己寫 namespace : dev, 裡面放一個 task 叫做 fake,fake 資料用 Populator 生) # 請自行練習

25 changes: 0 additions & 25 deletions manuscript/chapter-07.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# 練習作業 7 - 撰寫自動化 Rake 以及 db:seed


### 作業目標

用 Rake 撰寫自動化步驟,生假資料。
Expand All @@ -19,27 +18,3 @@
* [Ruby on Rails Rake Tutorial](http://jasonseifer.com/2010/04/06/rake-tutorial)
* [What’s New in Edge Rails: Database Seeding](http://ryandaigle.com/articles/2009/5/13/what-s-new-in-edge-rails-database-seeding)




# 練習作業 8 - 將 Groupme deploy 到租來的 VPS


### 作業目標

在租來的 VPS 上面建置 Ruby on Rails production 環境,使用 Ruby Enterprise Edition 與 mod_rails。使用 [Capistrano](https://github.com/capistrano/capistrano/wiki) 佈署 application。

### 練習主題

* 學會如何自動部署專案
* 使用 capistrano 自動部署專案
* 操作 cap deploy:setup
* 操作 cap deploy
* 操作 cap deploy:rollback
* 操作 cap deploy:restart


### 參考資料

* [rails-nginx-passenger-ubuntu](https://github.com/jnstq/rails-nginx-passenger-ubuntu)
* [AWDR4](http://pragprog.com/titles/rails4/agile-web-development-with-rails) deploy 章節
29 changes: 29 additions & 0 deletions manuscript/chapter-08-1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Ch 8.1 佈署 Rails Production 所需要的環境

佈署 Rails Application 是件說簡單很簡單,說複雜也很複雜的事。佈署的手法有很多種搭配,筆者最推薦的其實是在 Ubuntu / Debian 安裝 Ruby Enterprise Edition,web sever 使用 nginx + mod_rails 的組合。之後再撰寫 Capistrano 的 recipe 來 deploy。


### 為什麼要用獨立的 Ruby 版本,而不使用系統 Ruby?

因為系統 Ruby 通常綑綁了背後的套件系統(RubyGem),Rails 是個腳步前進很快的生態圈。而各樣相依套件有時候也會限定 RubyGem 的版本。很多時候,在開發或佈署上就會踩到大地雷。

所以會建議在系統上跑獨立的 Ruby。

### 為什麼要用 Ubuntu / Debian ,而不是使用 CentOS?

還是跟 Rails 是個腳步前進很快的生態圈有相當大的關係。Gem 的前進腳步很快,很多時候只 compatible 新的 library,而 CentOS 上很多 package 都已經 outdate 了。實際佈署上會踩到很多雷。而 Ubuntu / Debian 上的 package 更新速度非常快。所以也是首選。


### 有沒有 Best Practice 懶人包?

有。其實佈署真的不算是件易事,在佈署中最容易踩到的雷當數 ImageMagick ( rmagick gem) 與 MySQL ( mysql2 gem)。偏偏這幾乎是每個網站最常會用到的兩個 gem。而且裝爛了很難重裝。

這是我們公司標準用來裝機的 Step by Step guide: <https://github.com/rocodev/guides/wiki/setup-production-development> 基本上已經排除不少裝機時可能會遇到的狀況。


### 哪裡買域名和租 VPS?


我是在 enom.com 買域名,管理介面還算蠻好用的。

至於 VPS 是去 [Linode](http://linode.com/) 租的。算便宜大碗,速度上也能接受。若純練習也可到 [AWS EC2](http://aws.amazon.com/ec2/) 租東京的 micro instance。
97 changes: 97 additions & 0 deletions manuscript/chapter-08-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{::pagebreak :/}

## Ch 8.2 Capistrano

[Capistrano](https://github.com/capistrano/capistrano/wiki) 是 37 signals 開發的一套 automate deploy tool。也是許多 Rails Developer 推薦的一套佈署工具。


也許你要問,為什麼要用工具 deploy 專案呢?那是因為佈署 application 是由數道繁瑣的手續構成。首先,Rails 佈署程式並不像 php 那樣簡單,上傳檔案成功就完事了。要佈署一個 Rails Application,你必須連到遠端 server,然後 checkout 程式碼,跑一些 migration,重開 server 生效,重開 memcached,重開 search daemon ....

這些連續動作有時候往往一閃神即是災難。

而手動 deploy 在只有一個人一台機器時還勉強說得過去。當開發人員一多或機器一多,馬上就會要了大家的命。

Capistrano 固然強大,但官方網站的文件卻讓人不易讀懂。 Bootstrappets 內建了一個已經寫好的 recipe,可以直接使用。

{::pagebreak :/}

~~~~~~~~
# -*- encoding : utf-8 -*-

raw_config = File.read("config/config.yml")
APP_CONFIG = YAML.load(raw_config)

require "./config/boot"
require "bundler/capistrano"
require "rvm-capistrano"

default_environment["PATH"] = "/opt/ruby/bin:/usr/local/bin:/usr/bin:/bin"

set :application, "groupme"
set :repository, "[email protected]:example/#{application}.git"
set :deploy_to, "/home/apps/#{application}"

set :branch, "master"
set :scm, :git

set :user, "apps"
set :group, "apps"

set :deploy_to, "/home/apps/#{application}"
set :runner, "apps"
set :deploy_via, :remote_cache
set :git_shallow_clone, 1
set :use_sudo, false
set :rvm_ruby_string, '1.9.3'

set :hipchat_token, APP_CONFIG["production"]["hipchat_token"]
set :hipchat_room_name, APP_CONFIG["production"]["hipchat_room_name"]
set :hipchat_announce, false # notify users?

role :web, "groupme.com" # Your HTTP server, Apache/etc
role :app, "groupme.com" # This may be the same as your `Web` server
role :db, "groupme.com" , :primary => true # This is where Rails migrations will run

set :deploy_env, "production"
set :rails_env, "production"
set :scm_verbose, true
set :use_sudo, false


namespace :deploy do

desc "Restart passenger process"
task :restart, :roles => [:web], :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
end


namespace :my_tasks do
task :symlink, :roles => [:web] do
run "mkdir -p #{deploy_to}/shared/log"
run "mkdir -p #{deploy_to}/shared/pids"

symlink_hash = {
"#{shared_path}/config/database.yml" => "#{release_path}/config/database.yml",
"#{shared_path}/config/s3.yml" => "#{release_path}/config/s3.yml",
"#{shared_path}/uploads" => "#{release_path}/public/uploads",
}

symlink_hash.each do |source, target|
run "ln -sf #{source} #{target}"
end
end

end

namespace :remote_rake do
desc "Run a task on remote servers, ex: cap staging rake:invoke task=cache:clear"
task :invoke do
run "cd #{deploy_to}/current; RAILS_ENV=#{rails_env} bundle exec rake #{ENV['task']}"
end
end

after "deploy:finalize_update", "my_tasks:symlink"

~~~~~~~~
52 changes: 52 additions & 0 deletions manuscript/chapter-08-3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{::pagebreak :/}


## Ch 8.3 Capistrano 常用指令

### cap deploy:setup

第一次使用,運行此行指令,Capistrano 就會遠端到機器上幫你把 Capistrano 所需的一些目錄和檔案先預備好

### cap deploy

Deploy 專案到遠端

### cap deploy:migrate

遠端執行 migration

### cap deploy:rollback

deploy 的這一版本爛了,想回到沒爛的上一版本。

### cap deploy:restart

純粹重開 application

## Ch 8.4 Deploy with Rails 4

Rails 4 在部署上 Server 時有時候會遇到 Asset Compile 不過的問題。

### Rails 3


`config/production.rb`

~~~~~~~~
config.serve_static_assets = false
config.assets.compile = false
~~~~~~~~


### Rails 4

在 Rails 4 上要修改成

~~~~~~~~
config.serve_static_assets = true
config.assets.compile = true
config.assets.compress = true
config.assets.configure do |env|
env.logger = Rails.logger
end
~~~~~~~~
21 changes: 21 additions & 0 deletions manuscript/chapter-08.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 練習作業 8 - 將 Groupme deploy 到租來的 VPS


### 作業目標

在租來的 VPS 上面建置 Ruby on Rails production 環境,使用 Ruby Enterprise Edition 與 mod_rails。使用 [Capistrano](https://github.com/capistrano/capistrano/wiki) 佈署 application。

### 練習主題

* 學會如何自動部署專案
* 使用 capistrano 自動部署專案
* 操作 cap deploy:setup
* 操作 cap deploy
* 操作 cap deploy:rollback
* 操作 cap deploy:restart


### 參考資料

* [rails-nginx-passenger-ubuntu](https://github.com/jnstq/rails-nginx-passenger-ubuntu)
* [AWDR4](http://pragprog.com/titles/rails4/agile-web-development-with-rails) deploy 章節

0 comments on commit 52499bc

Please sign in to comment.