Eason's blog

使用production mode啟動你的rails專案

Published on

Quick Reference:

$ RAILS_ENV=production rake db:migrate
$ rake secret //產生secret key
$ export SECRET_KEY_BASE=[貼入上個指令產生出來的密鑰]
$ vim config/initializers/assets.rb  //加入用到的assets路徑
確認各處引用assets的方法正確
$ RAILS_ENV=production rake assets:precompile
$ vim config/environments/production.rb  //將這行改成true: config.serve_static_assets = true
$ rails s -e production

什麼是 production 模式?為什麼要用它?

在通常情況下,直接在你的專案裡下$ rails s這條指令,我們是使用 development mode 來啟動你的專案

在 development 模式下,大部分的修改都會直接顯現在網頁上,方便開發

但實際讓系統上線,我們不會使用 development 模式,而是production 模式

在 production 模式裡,rails 會將 assets 預編譯在一起(pre-compile),並放在 public/資料夾底下以供存取,這能增進網站效能

使用 production mode 啟動 rails 專案

0.migrate 你的資料庫

production mode 和 development mode 的資料庫是分開的,所以你需要再 migrate 一次

$ RAILS_ENV=production rake db:migrate

1.修改 config/secret.yml,設定 production mode 的 secret_key_base

要順利運行 rails 程式,你需要設定一個叫secret_key_base的東西,它是 rails 用來認證瀏覽器 cookie 的一串密鑰。rails 已經幫你在 development mode 和 test mode 設定好了,但 production mode 沒有,你得自己來,它的設定在config/secret.yml這隻檔案,讓我們來看看它:

// development mode的設定
// 它使用 b1f4eb...3a9 這串密鑰(隨機生成的)
development:
  secret_key_base: b1f4eb6c1d97f627fbc0a3919fc27ab5f831200cdd0ea72317f404a2b9d878192bca27d92380f56051c60d0a364c86fe53d9b9866d487a17cf06582a783723a9

// test mode使用 fe9d...c3b 這串密鑰
test:
  secret_key_base: fe9d49b7edc8e3a4dfa47c0682974aca4572388e929ea3e4f037b3e8841747fc3029e030bbd102a62d372596b4d753dd0c419b7425a8dcceca3817cf7d5dbc3b

// production mode從執行環境裡抓 $SECRET_KEY_BASE 這個環境變數當作密鑰,但正常情況下該變數並不存在,所以出錯
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

你有兩種方法能設定 production mode 的 secret_key_base

(1)比較簡易的做法是直接寫死一串固定的密鑰給它:

// 前略...

production:
// 刪掉原本的 <%= ... %> ,替換成隨便一串長度30以上的英數組合字串給他當密鑰
	secret_key_base: iameasonchangiamhandsomeiamthekingoftheworldnoonecandefeatmeiwantagirlfriendiamaloserqq

(2)更安全的做法是把密鑰設在執行環境中:

$ rake secret // 生成一串密鑰,顯示在終端機上
$ export SECRET_KEY_BASE=[此處貼上你剛剛產生的密鑰] // 把密鑰設定至環境變數 $SECRET_KEY_BASE

但只做到這樣的話,重開終端機的話環境變數設定就消失了,所以可以把設定寫進環境設定檔裡頭

像我使用 zsh 的話,環境設定檔是./.zshrc 而 Mac 的 terminal 預設的 bash,則是./.bash_profile

// 在.zshrc中插入下面這行
export SECRET_KEY_BASE=[此處貼上你剛剛產生的密鑰]

到此你應該可以無錯誤地使用 production mode 開啟你的 rails 專案了,你可以下$ rails s -e production來開啟伺服器,並且用瀏覽器連至localhost:3000查看目前的結果

你的畫面應該跟我很像,怎麼醜不拉幾的?我不眠不休設計出來的精美網頁呢?

Imgur

那是因為你還沒有告訴 rails 你用到了哪些設計元素,接下來的步驟教你怎麼做:

2.告訴 rails 你有哪些 assets 需要被 pre-compile

前面我們提過,使用 production mode 的理由是增進網頁讀取效能,方法是預編譯(pre-compile)各類 assets,而你需要手動告訴 rails 你有哪些 assets 需要預編譯,除了圖檔,所有使用到的 assets 都需要加入裡頭,如 js、css 檔

方法是更新config/initializers/assets.rb這隻檔案,加入你有使用到的 assets 的路徑:

// 前略...
// 後面加入這一行,裡頭放入你要precompile的檔案
Rails.application.config.assets.precompile += [
  'bootstrap.js', // 請幫我compile vendor/assets/javascripts/bootstrap.js 這支檔案
	'courses/content.js', // 還有 app/assets/javascripts/courses/content.js
	'courses/chart.js',  // app/assets/javascripts/courses/chart.js 也要
	'new-index.css', // 還有這個css,它在app/assets/stylesheets/new-index.css.scss
	'login.css', // app/assets/stylesheets/login.css.erb也要
	'newcomer/*.css', // app/assets/stylesheets/newcomer/裡面的css檔都要!
	'NotoSans-Regular-ttf' // 這個是字形檔唷!它在app/assets/fonts/NotoSans-Regular-ttf
]

rails 會去 app/assets/vendor/assets/ 這兩個資料夾去找你的 assets 檔案,並且會根據副檔名尋找對應的路徑:

  • js 檔會去找底下的 javascripts/
  • css 檔會去找底下的 stylesheets/
  • font 檔會去找底下的 fonts/
  • image 檔會去找底下的 images/

但 rails 預設會幫你 compile 所有的圖檔,所以.png、.jpg 等圖檔就不用加進去

3.確認你引入 assets 的方法有沒有誤

compile 後的 assets,檔名會改變,所以傳統引入 assets 的方法會失效,必須改用 rails 提供的方法

  • 引入 js 檔使用 <%= javascript_include_tag 'your-js-path' %>
  • 引入 css 檔使用 <%= stylesheet_link_tag 'your-css-path' %>
  • 引入圖檔使用 <%= image_tag 'your-image-path' %>
  • js 檔裡要再引入 asset 請使用 <%= asset_path('your-img-path') %>

4.Pre-compile it!

在你的專案目錄裡下指令:

$ RAILS_ENV=production rake assets:precompile

就會將 assets pre-compile 進/public/assets 裡頭

5.修改 production 的模式設定

雖然 compile 了,但 production 模式預設是不會讓使用者讀取/public/assets 的檔案

必須修改 config/environments/production.rb 這個檔案

將位在第 24 行左右的

config.serve_static_assets = false

改為 true:

config.serve_static_assets = true

6.使用 production mode 啟動吧!!

在專案的目錄裡下指令:

$ rails s -e production

就可以使用 production mode 開啟你的 rails 專案啦!

使用瀏覽器連入localhost:3000,就可以看到你速度大幅提升的美麗網頁啦!

imgur


測試環境:

  • OS: Mac OS X
  • Rails version: 4.2.6
  • Ruby version: 2.0.0p481
  • Shell: zsh