Rails 線上持續整合部署(CI) 使用-Docker架構

docker-logoDocker

Docker

Docker的優點相信很多人都知道了, 並也開始導入Docker, 我們大約在半年前開始將所有的線上環境全部Docker化

早期在部署應用程式環境的時候, 並不是簡單的安裝一個程式或是相關套件等等, 才能完整的安裝一可以上線的正式環境 但是問題是並不是每次安裝都能夠順利, 例如:版本的相依問題, 等等等….

例外如果當初的應用程式是安裝在早期的作業系統上開發的 如果時過境遷, 作業系統已經升級, 相關套件也已經升級, 因為應用程式和當初開發時的一些套件都有相依性 這時要將當初的應用程式跑在當初的環境下, 會比安裝全新的更加不容易 但是如果當初將整個設定和應用程式的版號,作業系統等和相關套件做成一個Docker 這樣之後只需要執行這個Docker就可以重現當初的整個環境了 應用程式頁能正確運作了

所以發展出來的Ansibe和chef這種自動換安裝的伺服器相關套件的解決方案 但是這個個人覺得還有有一些局限性, 例如:作業系統平台不一樣 都還需要再做一些修正

Docker的出現解決了很多問題, 例如任何的作業系統只要有安裝Docker, 跑起來的結果是一樣的 代表不用再局限於安裝目標的作業系統和作業系統版本, 目前Mac,Linux和Windows都已經可以在上面運作Docker 了

他有別於以前作業系統的虛擬化,他是應用程式的虛擬化, 他在裡面包了一個很簡易的Linux的核心, 讓你感覺不出來的他和原生的應用程式跑在作業系統上有什麼差別, 因此在Docker裡面就可以將當初已經安裝的作業系統版本包含在裡面了, 例如:ubuntu14.04 LTS, 如果這個Docker 跑在CentOS上面, 其實他的整個運作就像是跑在ubuntu14.04 LTS上一樣, 因此才能做到完整的跨平台的運作

CI(Continuous integration, CI) 持續整合 CI是為了提高程式碼的品質,維持系統或是網站的穩定性, 他的核心理念就是, 當有新的程式碼被提交時, 就會自動進行一連串的自動化步驟:編譯,測試,和部署 等

如果是Compile語言的話, 就會先進行編譯看是否程式碼可以通過自動化編譯 再來就是最重要的自動化測試, 當一個新功能完成, 或是新的程式碼提交後, 很難保證 網站或是系統可以所以的功能都是在事先預料的情況下運作, 如果只是進行人工驗證, 通常會有預想不到且沒有驗證到的情況發生, 而造成網站出現沒事先預料的錯誤

因此做自動化測試將所有應該要驗證的功能都透過自動化去驗證一遍 自動化測試包含:測試每個class或是method的正確性的單元測試, 測試API是否正確運作, 整合測試等

線上Rails的Production環境, 且所有的服務都是運作在Docker上面, 該怎麼架設CI環境呢?

簡述如下: 有時間再補足

GitLab

Git版本控制是CI環境的核心

Jenkins

Jenkins && GitLab Plugins

GitLab有和Jenkins整合的Plugins 當有新的程式碼被commit時, 會自動Triger Jenkins執行自動化測試的動作

Capistrano && Docker

Capistrano是Rails的常用的自動化部屬工具

利用Capistrano自動將遠端的最新的Rails Code build一個最新的Docker

然後跑起來, 如果有自己架設 Docker registry 可以直接運行 速度會快很多

Jenkins && Capistrano 自動化部屬

利用Jenkins去呼叫Capistrano做自動化部屬

Run Auto Tesing in a clear Docker

在做自動化測試有一個很重要的要注意的地方, 就是要使用乾淨的環境進行測試 利用Jenkins Build一個乾淨且專門用於跑自動化測試的環境

[Rails]今天在用購物車時發現一個Session問題

Session換頁之後, 商品沒有紀錄上去

查了之後發現是 From for 在新增商品沒 CSRF的auth code沒有新增

造成對應不到Session

所以每次新增商品時 都會重新開一個Session

所以造成購物車的商品不會累加

另外

由於Session裡面存的是購物車的是一個ruby物件

所以如果用 cookie store 由於 cookie無法儲存物件

所以用cookie會失敗

這個是由在Rails 4.1 之後的更新所做的修正

可參考 1. http://guides.rubyonrails.org/upgrading_ruby_on_rails.html 2. http://blog.plataformatec.com.br/2014/04/3-features-from-rails-4-1-that-im-excited-about/

之前Rails可以將Ruby物件放在Cookie的原因是他使用了 Marshal.dump and Marshal.load 來做物件的serialized (and deserialized)

但是由於這種做法,假如hacker如果拿到你的cookie加密的key就可以從你的cookie 解密出你存在裡面的物件, 所以降低了網站的安全性

因此Rails 4.1的更新, 讓Cookie只能儲存一些簡單的資料, 例如:string, integer, hash, array等 複雜物件就無法儲存

但也不是無法儲存, 只是物件的serialized (and deserialized) 就必須自己做了